使用RowSorter的Java fireTableRowsInserted(int,int)

时间:2014-09-24 15:23:12

标签: java swing jtable

我有一个扩展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()对我来说非常昂贵。不能顺其自然。

2 个答案:

答案 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延迟处理的想法导致异常。