2014-09-24 5 views
1

У меня есть модель таблицы, которая расширяет AbstractTableModel и базу данных, которая используется для этой модели. Некоторые процессы динамически добавляют строки к этой модели и запускают fireTableRowsInserted (lastRow, lastRow) каждый раз, когда строка добавляется в базу данных. Все работает нормально, если я не добавлю сортировщик к этой модели. После применения сортировщика fireTableRowsInserted (lastRow, lastRow) бросает java.lang.ArrayIndexOutOfBoundsException, когда строки все еще добавляют к модели и отображаются в GUIl.Java fireTableRowsInserted (int, int) с RowSorter

Все процессы/потоки, взаимодействующие с компонентами Swing, отправляются на EDT. Ниже приведена полная трассировка стека для этого исключения.

java.lang.ArrayIndexOutOfBoundsException: 281 
at javax.swing.DefaultRowSorter.setModelToViewFromViewToModel(DefaultRowSorter.java:734) 
at javax.swing.DefaultRowSorter.rowsInserted0(DefaultRowSorter.java:1063) 
at javax.swing.DefaultRowSorter.rowsInserted(DefaultRowSorter.java:868) 
at javax.swing.JTable.notifySorter(JTable.java:4272) 
at javax.swing.JTable.sortedTableChanged(JTable.java:4120) 
at javax.swing.JTable.tableChanged(JTable.java:4397) 
at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:296) 
at javax.swing.table.AbstractTableModel.fireTableRowsInserted(AbstractTableModel.java:231) 
at View.AllData.CenterSection.DataModel$1.run(DataModel.java:143) 
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311) 
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744) 
at java.awt.EventQueue.access$400(EventQueue.java:97) 
at java.awt.EventQueue$3.run(EventQueue.java:697) 
at java.awt.EventQueue$3.run(EventQueue.java:691) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75) 
at java.awt.EventQueue.dispatchEvent(EventQueue.java:714) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) 
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) 
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82) 

Возможно, это может быть причина этого исключения? и потенциальные решения. Сейчас около 7-8 часов, когда я пытаюсь это понять, но ничего не нашел. Любая помощь будет ценить меня.

Заранее спасибо.

Данные, которые мне нужно отображать, очень велики, поэтому fireTableDataChanged() для меня очень дорог. Не могу с этим поделать.

ответ

1

Скорее всего, вы забыли заявление Sorting and Filtering: «При использовании сортировщика всегда помните о переводе координат ячейки».

0

В очень похожей ситуации OP, мой код это:

 glosEntryTableModel.addElement(ge); 
     int index = this.glseTable.convertRowIndexToView(glosEntryTableModel.getIndexOf(ge)); 
     // int index = glosEntryTableModel.getIndexOf(ge); 
     glosEntryTableModel.fireTableRowsInserted(index, index); 

Как вы видите, я пытался с обеими моделями и просмотреть координаты, и все же я получаю исключение при вызове к fireTableRowsInserted , как ОП.

Debugging, я видел, что fireTableRowsInserted в AbstractTableModel содержит этот код:

public void fireTableRowsInserted(int firstRow, int lastRow) { 
    fireTableChanged(new TableModelEvent(this, firstRow, lastRow, 
         TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); 
} 

и Java API Docs говорит, что

TableModelEvent используется для уведомления слушателей, что табличная модель изменилась. Событие модели описывает изменения в TableModel и все ссылки на строки и столбцы находятся в координатной системе модели

поэтому нет никакой необходимости переводить координаты, если вы уже используете модель координаты. Как OP, в моем случае строка фактически вставлена ​​в JTable, и это означает, что даже если она вставлена ​​/ отображена в другой строке в представлении, чем в модели, количество строк должно быть одинаковым, при условии, что никакая фильтрация не выполняется (это мой случай, действительно).

На данный момент я могу только думать, что некоторая обработка в JTable или TableRowSorter задерживается, в результате чего fireTableRowsInserted фактически называет строку, которая еще не существует (пока) в представлении. Но тогда, разве это не должно быть причиной использования этого метода? Может быть, это ошибка в JDK?

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

ТИА

Update: только что понял, что у меня есть довольно много и тот же код в той же форме для других JTable и не подведет.Единственное различие заключается в том, что эта вторая таблица содержит только пару строк, тогда как другая, код которой я цитировал и запускает исключение, управляет прямо сейчас около 200 строк. Поэтому я склоняюсь к идее отсроченной обработки JDK, вызывающей исключение.

Смежные вопросы