ADDITIONAL SYSTEM INFORMATION :
Windows 10 Pro 19045
A DESCRIPTION OF THE PROBLEM :
If nothing is selected, calling setAnchorSelectionIndex() will cause table cells to fail to render. There are a large number of cases with slightly different behavior; for example, if cell selection is disabled, the setAnchorSelectionIndex()/setLeadSelectionIndex() calls appear to work, but when the table loses focus, the cell goes blank. Otherwise, depending on the selection mode, a single cell or an entire row may go blank. Debugging with certain breakpoints in JTable code appears to affect the outcome; sometimes the cells are rendered and sometimes not.
REGRESSION : Last worked in version 8u401
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a JTable with at least one row where every cell has a visible text value. Attempt to give focus to a cell by setting the anchor and lead indices for both row and column selection models.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A focus rectangle should appear around the cell value. This works in Java 8.0.402, 17.0.5, and 21.0.2; no other versions were tested.
ACTUAL -
The entire row goes blank. Forcing a redraw (e.g. by clicking in the row) restores the cell contents.
---------- BEGIN SOURCE ----------
import java.lang.reflect.InvocationTargetException;
import java.util.stream.IntStream;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.table.DefaultTableModel;
import static javax.swing.WindowConstants.EXIT_ON_CLOSE;
public class JTableSelection {
private static final int ROW_COUNT = 3;
private static final int COLUMN_COUNT = 3;
private static final int EXPECTED_FOCUSED_CELL_ROW = 1;
private static final int EXPECTED_FOCUSED_CELL_COLUMN = 1;
public static void main(final String[] args) throws InterruptedException, InvocationTargetException {
SwingUtilities.invokeAndWait(JTableSelection::demo);
}
private static void demo() {
final JTable table =
new JTable(new DefaultTableModel(ROW_COUNT, COLUMN_COUNT));
IntStream.range(0, ROW_COUNT).forEach(row ->
IntStream.range(0, COLUMN_COUNT).forEach(column ->
table.getModel().setValueAt("(" + row + ", " + column + ")", row, column)));
final Timer timer = new Timer(5000, event -> {
// Only this first call is necessary to reproduce.
table.getSelectionModel().setAnchorSelectionIndex(EXPECTED_FOCUSED_CELL_ROW);
table.getSelectionModel().setLeadSelectionIndex(EXPECTED_FOCUSED_CELL_ROW);
table.getColumnModel().getSelectionModel().setAnchorSelectionIndex(EXPECTED_FOCUSED_CELL_COLUMN);
table.getColumnModel().getSelectionModel().setLeadSelectionIndex(EXPECTED_FOCUSED_CELL_COLUMN);
});
timer.setRepeats(false);
timer.start();
final JFrame frame = new JFrame();
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setContentPane(table);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Only use methods like JTable.changeSelection(), instead of setting the anchor/lead manually. This doesn't have the same effect because it changes the selection in addition to the focus.
Possible related issues:
https://bugs.openjdk.org/browse/JDK-8258969
https://bugs.openjdk.org/browse/JDK-4870710
FREQUENCY : always