FULL PRODUCT VERSION :
java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.10586]
A DESCRIPTION OF THE PROBLEM :
I have JTable with column sorting and multiple selection, and row sorter's sortOnUpdates is set to true. As data in table is refreshing all the time, I call tableModel.fireTableRowsUpdated(row, row) on every update, which calls by stack JTable.restoreSortingSelection(). And all is OK, but if you're dragging your mouse for multiple selection at this time, all selection disappears except one single row which is under the mouse at the time.
What I found:
There is the call At JTable:4217
SwingUtilities2.setLeadAnchorWithoutSelection(selectionModel, lead, lead);
I presume that here is a typo, because this call should set both - lead and anchor - for selection model. Here should be
SwingUtilities2.setLeadAnchorWithoutSelection(selectionModel, lead, selection[selection.length - 1]);
REGRESSION. Last worked in version 8u101
ADDITIONAL REGRESSION INFORMATION:
java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the source code given. Try to drag mouse over the table to select few rows. Selection is cleared every 0.5sec.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Selection shouldn't be cleared
ACTUAL -
Selection is cleared (except currently mouse-hovered row)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BoxLayout;
import javax.swing.DefaultRowSorter;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.RowSorter;
import javax.swing.ScrollPaneConstants;
import javax.swing.SortOrder;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.WindowConstants;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
public class SortingTableSelectionBug {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
start();
}
});
}
private static void start() {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
final JTable table = new JTable(new DefaultTableModel(5, 4));
for (int i = 0; i < table.getRowCount(); i++) {
for (int col = 0; col < table.getColumnCount(); col++) {
table.setValueAt(String.valueOf(i), i, col);
}
}
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
table.setRowSorter(new TableRowSorter(table.getModel()));
((DefaultRowSorter)table.getRowSorter()).setSortsOnUpdates(true);
List<RowSorter.SortKey> sortKeys = new ArrayList<>();
sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING));
table.getRowSorter().setSortKeys(sortKeys);
JPanel tablesPanel = new JPanel();
tablesPanel.setLayout(new BoxLayout(tablesPanel, BoxLayout.Y_AXIS));
tablesPanel.add(table);
JScrollPane scrollPane1 = new JScrollPane(tablesPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
contentPane.add(table.getTableHeader());
contentPane.add(scrollPane1);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationRelativeTo(null);
Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
((AbstractTableModel)table.getModel()).fireTableRowsUpdated(0, 0);
}
});
timer.start();
frame.setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
JTable:4217
strange call
SwingUtilities2.setLeadAnchorWithoutSelection(selectionModel, lead, lead);
I presume that here is a typo, because this call should set both - lead and anchor - for selection model. Here should be
SwingUtilities2.setLeadAnchorWithoutSelection(selectionModel, lead, selection[selection.length - 1]);