ArrayIndexOutOfBoundsException: -1 при создании JTable / преобразование таблицы - PullRequest
2 голосов
/ 24 октября 2011

Я прочитал все темы, которые выглядели так, как будто они могли решить мою проблему, и я также прочитал все ответы здесь, но я все еще нахожусь в своем уме.Я не уверен, почему выбрасывается исключение, хотя я чувствую, что это может быть связано с threading.Если это произойдет, пожалуйста, дайте мне знать, где включить new Runnable() и invokeLater() или invokeAndWait(), поскольку я пробовал это безрезультатно.

Пожалуйста, потерпите меня, пока я вам даюкод, который приводит к исключению + трассировка стека (ниже).

EDIT : я включил число syso s в раздел AnnoTable непосредственно перед вызовом tableChangedи они не отображаются в консоли, поэтому я думаю, что проблема должна возникнуть даже до того, как приложение достигнет этой точки, то есть, когда оно вызывается из AAView или когда создаются данные и модель таблицы ...

РЕДАКТИРОВАТЬ II : Проблема заключалась в перезаписанном методе tableChanged.Это, очевидно, вызовет исключение.Я также удалил вызов tableChanged() (который не будет иметь значения).Теперь у меня есть другая проблема: понимание того, как изменение базовых данных (AnnoData) может автоматически обновлять таблицу.Хотя это возможно для другого запроса (после расширенного поиска в Google), пожалуйста, не стесняйтесь публиковать полезные комментарии в этой теме, так как я буду продолжать читать его ... СПАСИБО МНОГО за все полезные комментарии и советы!

EDIT III: * Я решил проблему.Мне нужно было создать экземпляр другого объекта из AnnoData, передать его новому экземпляру AnnoTableModel, установить этот экземпляр на мою таблицу и ТОГДА fireTableDataChanged().

РЕДАКТИРОВАТЬ IV: Хорошопоэтому fireTableDataChanged() (как используется в EDIT III) в конце концов не требуется.Я все еще хотел бы использовать это вместо того, чтобы создавать новые объекты все время.Я думаю, мне следует задать новый вопрос ... Спасибо!

Этот метод в AAView должен создать объект, расширяющий JTable, поместить его в JScrollPane и т. Д. (Последний работает).

private JPanel createAnnoTablePanel() {
    annoTablePanel = new JPanel();
    annoTable = new AnnoTable(aameth);
    setAnnoTable(annoTable);
    JScrollPane scrollPane = new JScrollPane(getAnnoTable());
    annoTablePanel.add(scrollPane);
    return annoTablePanel;
}

Вот класс AnnoTable (aameth - это объект экземпляра, содержащий бизнес-логику для доступа к модели данных, работает нормально).

public class AnnoTable extends JTable implements TableModelListener
{

  public AnnoTable(AAMethods aameth)
  {

     int tokenCount = aameth.getTokenCount();

     AnnoData annoData = new AnnoData(aameth); // cf. below, AnnoData is a Vector(Vector<Object>,String[])

     TableModel tableModel = new AnnoTableModel(annoData.getAnnoData(),
     // AnnoTableModel extends AbstractTableModel(Vector, String[])
     annoData.getColTitles());
     setModel(tableModel);
     getModel().addTableModelListener(this);
     TableModelEvent tme = new TableModelEvent(tableModel);
     this.tableChanged(tme);
     setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     setCellSelectionEnabled(true);
     getColumnModel().getSelectionModel().addListSelectionListener(new AnnoTableSelectionListener(this));
     setPreferredScrollableViewportSize(this.getPreferredSize());

  }

  public void tableChanged(TableModelEvent e) {
  int row = e.getFirstRow();
     int column = e.getColumn();
     AbstractTableModel model = (AbstractTableModel)e.getSource();
     String columnName = model.getColumnName(column);
     Object data = model.getValueAt(row, column); // This is where the exception is thrown!
  }
}

Если вынужен исходный код для AnnoTableModel() (который является довольно общим расширением AbstractTableModel) или AnnoData (который создает Vector, содержащий три Vector<Object> и String[] для заголовков столбцов), пожалуйста, дайте мне знать.

Вот трассировка стека.

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.table.DefaultTableModel.getValueAt(Unknown Source)
at package.AnnoTable.tableChanged(AnnoTable.java:52)
at javax.swing.JTable.setModel(Unknown Source)
at javax.swing.JTable.<init>(Unknown Source)
at javax.swing.JTable.<init>(Unknown Source)
at package.AnnoTable.<init>(AnnoTable.java:25)
at package.AAView.createAnnoTablePanel(AAView.java:464)
at package.AAView.createNorthPanel(AAView.java:455)
at package.AAView.displayAndAnnotate(AAView.java:444)
at package.AAView.loadProject(AAView.java:333)
at package.AAView.actionPerformed(AAView.java:286)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Actions.actionPerformed(Unknown Source)
at javax.swing.SwingUtilities.notifyAction(Unknown Source)
at javax.swing.JComponent.processKeyBinding(Unknown Source)
at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(Unknown Source)
at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(Unknown Source)
at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(Unknown Source)
at javax.swing.JMenuBar.processKeyBinding(Unknown Source)
at javax.swing.KeyboardManager.fireBinding(Unknown Source)
at javax.swing.KeyboardManager.fireKeyboardAction(Unknown Source)
at javax.swing.JComponent.processKeyBindingsForAllComponents(Unknown Source)
at javax.swing.JComponent.processKeyBindings(Unknown Source)
at javax.swing.JComponent.processKeyEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Я вижу там EDT, так что, как я понял, это действительно может быть проблемой многопоточности.Тем не менее, я не знаю, как узнать, с чего мне начинать новый Thread (или вызывать new Runnable().

. На заметке, исключение начало появляться только после того, как я изменил AnnoTableрасширить JTable вместо JPanel. Изначально AnnoTable не только создавал таблицу, но также оборачивал ее в область прокрутки и добавлял ее в новый JPanel. Но потому что я хотел fireTableDataChanged изКласс, который знал только о AAView (который также содержит метод setAnnoTable()), я хотел сделать это правильно, тогда как раньше он работал просто отлично. Закон Мерфи?

Ответы [ 5 ]

5 голосов
/ 24 октября 2011

Индекс строки -1 (== TableModelEvent.HEADER_ROW) указывает, что структура модели полностью изменилась. Такое событие вызывается внутренне JTable на setModel. Прочитайте API документации TableModelEvent, чтобы полностью понять, какие типы / значения следует ожидать в tableChanged слушателя.

Кстати, @AKJ прав - нет необходимости запускать какие-либо TableModelEvents в коде вашей таблицы. Заставьте модель запускать события соответствующим образом

3 голосов
/ 24 октября 2011

У меня такое ощущение, что ваша проблема здесь:

TableModelEvent tme = new TableModelEvent(tableModel);      
this.tableChanged(tme); 
->
  int column = e.getColumn();     
  AbstractTableModel model = (AbstractTableModel)e.getSource();     
  String columnName = model.getColumnName(column); 

Поскольку вы не указали значение row или column, вызовы getColumn() и getRow() вернутся -1, который вы затем передаете на getValueAt().

Попробуйте посмотреть на конструктор для TableModelEvent .У этого есть варианты для того, чтобы указать те значения строки / столбца.

3 голосов
/ 24 октября 2011
TableModelEvent tme = new TableModelEvent(tableModel);
this.tableChanged(tme);

Я не вижу необходимости в этом звонке.Как указывалось другими авторами, это является причиной вашей проблемы.

Если вы правильно реализуете модель таблицы, при каждом обновлении модели таблицы jtable будет автоматически получать уведомления, и вам не нужно писать tableChanged.() метод также.Поэтому я заблудился, почему вам нужно явно вызывать tableChanged ().

Всякий раз, когда вы хотите обновить таблицу, просто обновите модель.Кроме того, на первый взгляд, кажется, что нет никакой проблемы с многопоточностью.

3 голосов
/ 24 октября 2011

Это означает, что вы передаете -1 как строку или столбец.Это недопустимо - убедитесь, что вы передали правильное значение.

0 голосов
/ 08 июля 2014

Ваш конструктор AnnoTable пропускает ссылки на не полностью созданный объект "this". Кроме того, регистрация Слушателей от конструктора небезопасна. введите описание ссылки здесь

Создайте свои объекты, выполняя наименьшее количество работы в конструкторе, а затем оперируйте полностью построенными объектами. Добавить слушателей, настроить модели, fireEvents и т. Д ...

...