Java fireTableRowsInserted (int, int) с RowSorter

1

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

Все процессы/потоки, взаимодействующие с компонентами 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() для меня очень дорог. Не могу с этим поделать.

Теги:
swing
jtable

2 ответа

1

Скорее всего, вы забыли слова " Сортировка и фильтрация": "При использовании сортировщика всегда помните о переводе координат ячейки".

0

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

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

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

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

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

и в документах Java API говорится, что

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

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

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

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

ТИА

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню