JDK-8041440 : OOB Exception on deleting all rows from filtered JTable
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • Submitted: 2013-04-04
  • Updated: 2014-11-21
  • Resolved: 2014-05-13
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
1.7.0_09

ADDITIONAL OS VERSION INFORMATION :
Windows, Linus, MacOS

A DESCRIPTION OF THE PROBLEM :
JTable.SortManager uses a DefaultListModel to cache the selection in a filtered table. DefaultListModel sets the lead selection to 0 (not -1) when all rows are deleted.

After the delete event, SortManager tries to restore the selection from that cached model, including restoring the lead. This calls convertRowIndexToView(0), and an exception occurs.



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See sample code.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread  " main "  java.lang.ArrayIndexOutOfBoundsException: 0
at javax.swing.DefaultRowSorter.convertRowIndexToView(DefaultRowSorter.java:486)
at javax.swing.JTable.convertRowIndexToView(JTable.java:2589)
at javax.swing.JTable$SortManager.restoreSelection(JTable.java:4033)
at javax.swing.JTable$SortManager.processChange(JTable.java:3985)
at javax.swing.JTable.sortedTableChanged(JTable.java:4117)
at javax.swing.JTable.tableChanged(JTable.java:4383)
at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:280)
at javax.swing.table.AbstractTableModel.fireTableRowsDeleted(AbstractTableModel.java:245)
at javax.swing.table.DefaultTableModel.removeRow(DefaultTableModel.java:447)
at TableFilterBug.main(TableFilterBug.java:22)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;

public class TableFilterBug {
public static void main(String[] args) {
DefaultTableModel model = new DefaultTableModel(1, 1);
JTable table = new JTable(model);

TableRowSorter<DefaultTableModel> sorter = new TableRowSorter<DefaultTableModel>(model);
table.setRowSorter(sorter);
table.getSelectionModel().setSelectionInterval(0, 0);

sorter.setRowFilter(new RowFilter<DefaultTableModel, Integer>() {
@Override
public boolean include(Entry<? extends DefaultTableModel, ? extends Integer> entry) {
return false;
}
});

model.removeRow(0);
}
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Create a subclass of TableRowSorter that returns -1 from convertRowIndexToView() if the index given is 0 and the model size is 0. Convert all uses of TableRowSorter to use this subclass instead.