A
Aloys Oberthuer
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)
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)