ADDITIONAL SYSTEM INFORMATION :
Kubuntu 17.10 (64-Bit) with JDK 10.0.1:
java 10 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+46)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)
A DESCRIPTION OF THE PROBLEM :
A mouse listener will be used to set the row(of a JTable) underneath the mouse cursor to the selected state. After using the clearSelection() method from JTable, when the mouse moves out of the current selected row, and the next row is not selectable, the previous selected row will be excluded from drawing and hence disappears.
Using this technique worked until latest JDK 8!
REGRESSION : Last worked in version 10.0.1
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See the sample code, which reproduces the problem.
I found out that same code in BasicTableUI has changed, which may cause the problem. In BasicTableUI.paint(...) there is the following check:
if (rMax != (table.getRowCount() - 1) &&
(table.getSelectedRow() == -1)) {
rMax = rMax - 1;
}
In situations where rMax is 1, this causes rMax to be 0 and the subsequently call of paintCells(...) excludes the cells of the row from being drawn because the inner loop with paintCell(... )is not running.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Rows do not disappear when selection is cleared and the mouse leaves this row.
ACTUAL -
Row is disappearing when mouse leaves the selected row and the next row underneath the cursor is not selectable.
---------- BEGIN SOURCE ----------
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableModel;
public class TableTest {
private static String[] rows = new String[] {
"Row1", "Row2", "Row3", "Row4", "Row5",
"Row6", "Row7", "Row8", "Row9", "Row10"};
public static void main(final String[] args) {
final DefaultTableModel model = new DefaultTableModel();
model.addColumn("Test", rows);
final JTable table = new JTable(model);
table.setRowHeight(25);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
final MouseAdapter adapt = new MouseAdapter() {
private boolean isRowSelectable(int rowIndex) {
return rowIndex % 2 == 0;
}
@Override
public void mouseMoved(final MouseEvent pE) {
final int row = table.rowAtPoint(pE.getPoint());
if (row > -1 && this.isRowSelectable(row)) {
table.setRowSelectionInterval(row, row);
} else {
table.clearSelection();
}
}
@Override
public void mouseEntered(final MouseEvent pE) {
final int row = table.rowAtPoint(pE.getPoint());
if (row > -1 && this.isRowSelectable(row)) {
table.setRowSelectionInterval(row, row);
} else {
table.clearSelection();
}
}
@Override
public void mouseExited(final MouseEvent pE) {
table.clearSelection();
}
};
table.addMouseListener(adapt);
table.addMouseMotionListener(adapt);
final JFrame frame = new JFrame();
frame.setSize(800, 300);
frame.add(table);
frame.setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Overwriting the getSelectedRow() method in JTable and returning -2 instead of -1 in case of a cleared selection bypasses the check in BasicTableUI.paint(...) and the rows will not disappear.
FREQUENCY : always