JDK-8032874 : ArrayIndexOutOfBoundsException in JTable while clearing data in JTable
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 7u45
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-01-28
  • Updated: 2014-10-15
  • Resolved: 2014-04-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8 JDK 9
7u72Fixed 8u20Fixed 9 b12Fixed
Related Reports
Duplicate :  
Relates :  
Description
Issue with Java version 7u45

Test case:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.DefaultRowSorter;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.RowFilter;
import javax.swing.table.DefaultTableModel;

final class TableDemo extends JPanel
{
  public TableDemo()
  {
    setLayout(new BorderLayout());
    add(_createGenericTable());
  }

  public static void main(String[] args)
  {
    JFrame frame = new JFrame("Generic Table Demo");
    frame.add(new TableDemo());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.pack();
    frame.setVisible(true);
  }

  private JPanel _createGenericTable()
  {
    JPanel p = new JPanel();
    p.setLayout( new BorderLayout(10, 0) );

    DefaultTableModel model = new DefaultTableModel(defaultModel,
                                                        defaultColumns);
    _table = new JTable(model);
    JScrollPane pane = new JScrollPane(_table);
    _table.setAutoCreateRowSorter(true);


    JPanel p1 = new JPanel();
    p1.setLayout(new FlowLayout());
    p1.add(pane);
    p.add(p1, BorderLayout.WEST);

    JPanel controls = new JPanel();
    final JTextField text = new JTextField(20);
    controls.add(text);
    text.addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent ae) {
                              RowFilter<Object,Object> startsWithAFilter = 
new RowFilter<Object,Object>() {
                                public boolean include(Entry<? extends 
Object, ? extends Object> entry) {
                                  for (int i = entry.getValueCount() - 1; i 
>= 0; i--) {
                                    
if(entry.getStringValue(i).contains(text.getText())) {
                                    // The value starts with "a", include it
                                      return true;
                                    }
                                  }
                                  // None of the columns start with "a"; 
return false so that this
                                  // entry is not shown
                                  return false;
                                }
                              };
                              
((DefaultRowSorter)_table.getRowSorter()).setRowFilter(startsWithAFilter);
                            }
                          });

    JButton clear = new JButton("Clear");
    clear.addActionListener(new ActionListener(){
                              public void actionPerformed(ActionEvent ae) {   
                                 
                                
((DefaultTableModel)_table.getModel()).setRowCount(0);
                              }
                            });
    controls.add(clear);
    p.add(controls, BorderLayout.EAST);

    return p;
  }

  private static String[] defaultColumns = new String[] { "Artist", "Album", 
"Genre", "Year", "Length" };

  private static String[][] defaultModel = new String[][] { new String[] { 
"The White Stripes", "Elephant", "Rock", "2003", "45:02" },
                                                            new String[] { 
"Oasis", "Definitely Maybe", "Rock", "1995", "48:21" },
                                                            new String[] { 
"James Brown", "20 All-Time Greatest Hits", "Soul", "1978", "55:12" },
                                                            new String[] { 
"Ali Farka Toure", "Savane", "Blues", "2006", "54:54" },
                                                            new String[] { 
"Django Reinhardt", "Djangologie", "Jazz", "1937", "34:11" },
                                                            new String[] { 
"The Beatles", "Abbey Road", "Pop", "1970", "34:12" },
                                                            new String[] { 
"Primus", "Frizzle Fry", "Rock", "1997", "38:23" }, 
                                                            new String[] { 
"AIR", "Moon Safari", "Electronic", "2000", "46:42" },
                                                            new String[] { 
"Iron Maiden", "Live After Death", "Metal", "1984", "85:23" },
                                                            new String[] { 
"Zero-7", "In The Waiting Line", "Downtempo", "2006", "45:02" },
                                                            new String[] { 
"The Rolling Stones", "Let It Bleed", "Rock", "1972", "37:23" },
                                                            new String[] { 
"Aretha Franklin", "I Never Loved A Man", "Soul", "1966", "39:23" },
                                                            new String[] { 
"Rammstein", "Mutter", "Metal", "2002", "44:12" },
                                                            new String[] { 
"Coldplay", "Viva La Vida", "Pop", "2008", "51:00" },
                                                            new String[] { 
"Art Of Noise", "In Visible Silence", "Electronic", "1986", "39:12" }, 
                                                            new String[] { 
"New Order", "Bizarre Love Triangle", "Electronic", "1985", "43:23" }, };

  private JTable _table;
}

1.Run TableDemo.java
2. You will see a Jtable (with data), a TextField and a Clear button (from 
left-right order)
3. Select the first row in the Table ("the White Stripes")
4. Now click on the textField next to the jtable, type "a" and then press 
ENTER key. This will filter the table to show only the rows that contain the 
character "a".
5. Now click on "Clear" button next to textfield. It will set the rowCount to 
zero on DefaultTableModel. (basically to remove all items from the table).

Once clear button is clicked you will see the following exception:


Exception in thread "AWT-EventQueue-0"
java.lang.ArrayIndexOutOfBoundsException: 0
at 
javax.swing.DefaultRowSorter.convertRowIndexToView(DefaultRowSorter.java:503)
at javax.swing.JTable.convertRowIndexToView(JTable.java:2619)
at javax.swing.JTable$SortManager.restoreSelection(JTable.java:4044)
at javax.swing.JTable$SortManager.processChange(JTable.java:3996)
at javax.swing.JTable.sortedTableChanged(JTable.java:4128)
at javax.swing.JTable.tableChanged(JTable.java:4394)
at 
javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:
 296)
at 
javax.swing.table.AbstractTableModel.fireTableRowsDeleted(AbstractTableModel.j
ava:261)
at javax.swing.table.DefaultTableModel.setNumRows(DefaultTableModel.java:321)
at 
javax.swing.table.DefaultTableModel.setRowCount(DefaultTableModel.java:339)
at 
oracle.javatools.ui.internal.theme.TableDemo$2.actionPerformed(TableDemo.java:
 78)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at 
javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at 
javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402
)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at 
javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.j
ava:252)
at java.awt.Component.processMouseEvent(Component.java:6505)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6270)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:729)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:688)
at java.awt.EventQueue$3.run(EventQueue.java:686)
at java.security.AccessController.doPrivileged(Native Method)
at 
java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java
 :76)
at 
java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java
 :87)
at java.awt.EventQueue$4.run(EventQueue.java:702)
at java.awt.EventQueue$4.run(EventQueue.java:700)
at java.security.AccessController.doPrivileged(Native Method)
atjava.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.ja
va:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:699)
at 
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:2
42)
at 
java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)

at 
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:1
50)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Process exited with exit code 0.


Comments
SQE is ok to take the fix in PSU14_04.
2014-05-29

Problem description: If JTable has Sorter and Filter and selected row is removed ArrayIndexOutOfBoundsException will be thrown. Suggested fix: The method restoreSelection() in SortManager class should invoke convertRowIndexToView() only when modelSelection is NOT empty.
2014-04-11