В форме JPanel есть JTable. По какой-то причине я начал получать следующую ошибку при открытии формы во второй раз (и все последующие разы) после выполнения некоторых операций с ней:
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)...
После некоторых исследований я обнаружил, что заголовокЭто вызывает всплывающее меню, достаточно просто вызвать всплывающее меню, затем закрыть форму, открыть ее и получить ошибку.
После еще одного исследования был найден обходной путь: выполните следующую команду перед настройкой формывидимый и ошибка исчезла:
header.setDraggedColumn(null);
Таким образом, это очевидно, столбец заголовка по какой-то причине перетаскивается перед открытием формы во второй раз. Существуют другие похожие формы в приложении, которые отлично работают с использованием того же или очень похожего кода. Но я не нашел никакой разницы, а также понятия не имею, когда или что устанавливает перетаскиваемый столбец для заголовка.
Как упоминалось ранее, достаточно просто вызвать всплывающее меню в заголовке (этосделано правой кнопкой мыши), чтобы иметь ошибку при открытии формы в следующий и следующий раз. Конечно, когда всплывающее меню не прикреплено, просто щелчок правой кнопкой мыши по заголовку не вызывает никаких проблем, поэтому он наверняка связан с всплывающим меню.
Всплывающее меню добавляется так:
header.setComponentPopupMenu(headerPopup);
И существует ActionListener, который выглядит следующим образом:
public class TableActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
//System.out.println("command: " + command);
switchCommands(command);
}
}
В форме есть только один его экземпляр:
public TableActionListener actionListener = new TableActionListener ();
И он добавляетсяк каждому пункту меню:
JMenuItem mi = new JMenuItem(menuItem.title);
mi.setActionCommand(menuItem.command);
mi.addActionListener(actionListener);
popup.add(mi);
Может быть, у кого-то был подобный опыт или хотя бы теоретические знания, чтобы объяснить, что на самом деле там происходит?
UPD: работая над минимальным рабочим примером, ятакже заметил, что такая ошибка исчезла, когда я убрал настройку модели для таблицы при отображении формы, поэтому раньше мой метод show
выглядел так:
@Override
public void show () {
objects.load();
jtProblemTable.setModel(objects.tableModel);
...
А теперь модель для таблицы установленав конструкторе формы, а метод show
равен
@Override
public void show () {
objects.load();
objects.tableModel.fireTableDataChanged();
...
и все работает нормально. Хотя до сих пор остается загадкой, почему столбец был перетащен ... продолжить работу над ним
UPD2: После внесения изменений в предыдущее обновление (скорее всего, изменение конструктора формы) я не могу воспроизвестиошибка больше, несмотря на восстановление кода, который был до обновления. Так что, скорее всего, это была ошибка NetBeans 8.2 (я использовал ее графический редактор форм). Конечно, я делал проект «Чистка и сборка» много раз, поэтому это было не так очевидно.