ArrayIndexOutOfBoundsException with DefaultTableModel

From: Aloys Oberthuer (aloys.oberthuer_at_gmx.net)
Date: 04/15/04


Date: Thu, 15 Apr 2004 23:54:42 +0200

Hi everyone,

i have got a problem with JTable. I created a small panel which includes
a JTable (in a JScrollPane) with a DefaultTableModel as model and 3
Buttons to add and remove rows and to clear the whole table. The problem
is after deleting a row, and clicking on the row which is now the last,
I always get ArrayIndexOutOfBoundsExceptions (see the StackTrace below).

I create the Table as follows:
                
DefaultTableModel dftM = new DefaultTableModel(2, 1);
                
tbl = new JTable();
tbl.setAutoCreateColumnsFromModel(false); // create my own ColumnModel
tbl.setShowHorizontalLines(true);
tbl.setShowVerticalLines(true);
tbl.setModel(dftM);
                
// build table column(s), custom renderer(s) and editor(s), etc.
// see below

All I do is invoke the following method in my code on a "delete row"
button action:
private void rowDelete() {
   int row = tbl.getSelectedRow();
   ((DefaultTableModel)tbl.getModel()).removeRow(row);
}

The table does redraw with one row less, but as I try to select another
row, I always get the Exception. The same thing happens after clearing
the Table which I do as follows:

public void tableDataReset() {
   DefaultTableModel dftM = new DefaultTableModel(1, 1);
   tbl.setModel(dftM);
}

I.e. I do create a new DefaultTableModel and get the same problem. It
looks like changing the model (deleting a row, replacing the model) did
not really affect the model or leaves it in an inconsistent state, which
I find especially strange with replacing the model. Sometimes after
deleting a row and adding an empty new one the 'empty' row contains the
content of the deleted row, which points in the same direction for me.
I tried using tbl.tableChanged(new TableModelEvent(dftM)) but that did
not help either. I have included the whole (executable) class and the
stacktrace - any help would be greatly appreciated. I use J2SE 1.4.2 on
a WindowsXp Sp1 System.

Aloys

CODE:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class SimpleTablePanel extends JPanel {
        
   private JTable tbl;
   private JScrollPane jsp;
   private JPanel pnlTable, pnlButtons;
   private JButton btAdd, btRemove, btClear;

        
   public SimpleTablePanel(String title, int tWidth, int tHeight) {
     super();
        
    createPanelTable(title, tWidth, tHeight);
    createPanelButtons();
                        
    this.setLayout(new BorderLayout());
    this.add(pnlTable, BorderLayout.CENTER);
    this.add(pnlButtons, BorderLayout.SOUTH);
}
        
        
private void createPanelButtons() {
   // create Button Panel
   pnlButtons = new JPanel(new FlowLayout(FlowLayout.LEFT));
                
   btAdd = new JButton("Add");
   btAdd.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent aE){
       SimpleTablePanel.this.rowAdd();
     }
   });
   btRemove = new JButton("Del");
   btRemove.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent aE) {
       SimpleTablePanel.this.rowDelete();
     }
   });
   btClear = new JButton("Clr");
   btClear.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent aE) {
       SimpleTablePanel.this.tableDataReset();
     }
   });

   pnlButtons.add(btAdd);
   pnlButtons.add(btRemove);
   pnlButtons.add(btClear);
}

private void createPanelTable(String title, int tWidth, int tHeight) {
   pnlTable = new JPanel();
                
   DefaultTableModel dftM = new DefaultTableModel(2, 1);
                        
   // next create Table
   tbl = new JTable();
   tbl.setAutoCreateColumnsFromModel(false); // create my own ColumnModel
   tbl.setShowHorizontalLines(true);
   tbl.setShowVerticalLines(true);
   tbl.setModel(dftM);
                
   // and build table column
   TableCellRenderer renderer = new DefaultTableCellRenderer();
                        
   JTextField txt = new JTextField(20);
   txt.setBorder(null);
   TableCellEditor editor = new DefaultCellEditor(txt);
                
   ((DefaultCellEditor)editor).setClickCountToStart(1);
                
   TableColumn column = new TableColumn(0, tWidth, renderer, editor);
   column.setHeaderValue(title);
   tbl.addColumn(column);
                
   // and put it in a JScrollPane
   jsp = new JScrollPane(tbl);
   jsp.setPreferredSize(new Dimension(tWidth,tHeight));
   pnlTable.add(jsp, BorderLayout.CENTER);
}
        
private void rowAdd() {
   int row = tbl.getSelectedRow();
   ((DefaultTableModel)tbl.getModel()).insertRow(row+1, new String[] {""});
}
private void rowDelete() {
   int row = tbl.getSelectedRow();
   ((DefaultTableModel)tbl.getModel()).removeRow(row);
}
public void tableDataReset() {
   DefaultTableModel dftM = new DefaultTableModel(1, 1);
   tbl.setModel(dftM);
}
        
public static void main(String[] args) {

   JFrame jf = new JFrame("Testframe");
   jf.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {System.exit(0);}
   });
                
   SimpleTablePanel jsF = new SimpleTablePanel("Table", 400, 300);
   jf.getContentPane().add(jsF, BorderLayout.CENTER);
   jf.pack();
   jf.setVisible(true);
}
}

STACKTRACE:
java.lang.ArrayIndexOutOfBoundsException: 2 >= 2
at java.util.Vector.elementAt(Vector.java:431)
atjavax.swing.table.DefaultTableModel.setValueAt(DefaultTableModel.java:633)
at javax.swing.JTable.setValueAt(JTable.java:1794)
at javax.swing.JTable.editingStopped(JTable.java:3167)
atjavax.swing.AbstractCellEditor.fireEditingStopped(AbstractCellEditor.java:124)
at
javax.swing.DefaultCellEditor$EditorDelegate.stopCellEditing(DefaultCellEditor.java:329)
at javax.swing.DefaultCellEditor.stopCellEditing(DefaultCellEditor.java:214)
at javax.swing.JTable.editCellAt(JTable.java:2510)
at
javax.swing.plaf.basic.BasicTableUI$MouseInputHandler.adjustFocusAndSelection(BasicTableUI.java:510)
at
javax.swing.plaf.basic.BasicTableUI$MouseInputHandler.mousePressed(BasicTableUI.java:494)
at java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:222)
at java.awt.Component.processMouseEvent(Component.java:5097)
at java.awt.Component.processEvent(Component.java:4897)
at java.awt.Container.processEvent(Container.java:1569)
at java.awt.Component.dispatchEventImpl(Component.java:3615)
at java.awt.Container.dispatchEventImpl(Container.java:1627)
at java.awt.Component.dispatchEvent(Component.java:3477)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:3483)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3195)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3128)
at java.awt.Container.dispatchEventImpl(Container.java:1613)
at java.awt.Window.dispatchEventImpl(Window.java:1606)
at java.awt.Component.dispatchEvent(Component.java:3477)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:456)
at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:201)
at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:145)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:137)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:100)


Loading