我有一个扩展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()对我来说非常昂贵。不能顺其自然。
答案 0 :(得分:1)
最有可能的是,您忘记了Sorting and Filtering格言,“使用分拣机时,请务必记住转换单元格坐标。”
答案 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。
调试,我发现AbstractTableModel中的fireTableRowsInserted包含以下代码:
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,但我也想找到更好的解决方案。
TIA
更新:刚刚意识到我和其他JTable在同一表格中有相同的代码并且没有失败。唯一的区别是第二个表只包含几行,而另一个代码我引用并触发异常的另一个表现在管理着大约200行。因此,我倾向于JDK延迟处理的想法导致异常。