In a JPanel form there is a JTable. For some reason I've started receiving the following error when opening the form second time (and all following times) after doing some operations in it:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Vector.elementData(Vector.java:737)
at java.util.Vector.elementAt(Vector.java:480)
at javax.swing.table.DefaultTableColumnModel.getColumn(DefaultTableColumnModel.java:294)
at javax.swing.plaf.basic.BasicTableHeaderUI.getHeaderRenderer(BasicTableHeaderUI.java:693)
at javax.swing.plaf.basic.BasicTableHeaderUI.paintCell(BasicTableHeaderUI.java:709)
at javax.swing.plaf.basic.BasicTableHeaderUI.paint(BasicTableHeaderUI.java:685)
at javax.swing.plaf.synth.SynthTableHeaderUI.paint(SynthTableHeaderUI.java:173)
at javax.swing.plaf.synth.SynthTableHeaderUI.update(SynthTableHeaderUI.java:144)
at javax.swing.JComponent.paintComponent(JComponent.java:780)...
After some investigation I've found, that a header popup menu is causing this, it's just enough to invoke the popup menu, then close the form, open it and receive the error.
After some more investigation an workaround was found: execute the following command before setting the form visible and the error is gone:
header.setDraggedColumn(null);
So it is obviuos, a header's column is set dragged for some reason before opening the form second time. The are other similar forms in the application which work fine using the same or very similar code. But I haven't found any difference, and also have no idea when or what is setting a dragged column for the header.
As mentioned before, it is enough just to invoke the popup menu on the header (it's done by right click) to have the error when opening form the next and the following times. Of course, when there is no popup menu attached, just right click on the header is not causing any problems, so it is related to the popup menu for sure.
The popup menu is added like this:
header.setComponentPopupMenu(headerPopup);
And there is an ActionListener which is like this:
public class TableActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
//System.out.println("command: " + command);
switchCommands(command);
}
}
There is only one instance of it in the form:
public TableActionListener actionListener = new TableActionListener ();
And it is added to each menu item:
JMenuItem mi = new JMenuItem(menuItem.title);
mi.setActionCommand(menuItem.command);
mi.addActionListener(actionListener);
popup.add(mi);
Maybe anyone had a similar experience or at least has theoretical knowledge to explain what is actually happening there?
UPD:
While working on a minimal working example I also noticed, that such error disappeared when I have removed setting a model for the table when showing the form, so before my show
method looked like:
@Override
public void show () {
objects.load();
jtProblemTable.setModel(objects.tableModel);
...
And now the model for the table is set in the constructor of the form, and show
method is
@Override
public void show () {
objects.load();
objects.tableModel.fireTableDataChanged();
...
and everything is working fine. Although, it is still a mystery, why a column was set dragged... continue working on it
UPD2: After the changes were done for the previous update (most probably modifiying the form constructor) I cannot reproduce the error anymore despite restoring the code which was before the update. So, most probably it was a bug of NetBeans 8.2 (I used its graphical form editor). Of course, I did Clean and Build Project many times before, so it was something not so obvious.