原因是什么

时间:2010-12-20 04:30:41

标签: java

这是我的第一个问题。首先,我是Java的新手,仍在努力理解事件。我有一个自定义模型的JTable,它扩展了AbstractTableModel,一个实现TableModelListener的CustomTableModelHandler和一个自定义TableCellRenderer,以显示一些自定义工具提示(来自不同列的数据的组合)。用户只能选择单行,我选中了autocreaterowsorter选项。删除行时,我使用此方法:

public void removeRow(int modelIndex) {
    fireTableRowsDeleted(modelIndex, modelIndex);
    rowData.remove(modelIndex);
}

我第一次触发数据更改事件的原因是我想用包含我要删除的行的数据的文本更新JLabel(可能有一种更优雅的方式)。我总是传递模型索引行,我已经尝试清除视图中的选择,但这没有帮助。我似乎无法100%重现错误的次数,但似乎它在我编辑一行后的大部分时间都发生了,有一个列排序处于活动状态然后删除一行(这实际上是错误后的操作)发生)。

所以,问题是:我怎么能说出我的问题的原因是什么?整个代码有点太大了,不能在这里发布,但如果有人想看一下,我可以提供它。

错误(出现很多时间):

run:
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at java.util.ArrayList.RangeCheck(ArrayList.java:547)
        at java.util.ArrayList.get(ArrayList.java:322)
        at Contacts.ContactsGUI$CustomTableModel.getValueAt(ContactsGUI.java:1975)
        at javax.swing.JTable.getValueAt(JTable.java:2686)
        at javax.swing.JTable.prepareRenderer(JTable.java:5703)
        at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2072)
        at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:1974)
        at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1770)
        at javax.swing.plaf.ComponentUI.update(ComponentUI.java:143)
        at javax.swing.JComponent.paintComponent(JComponent.java:752)
        at javax.swing.JComponent.paint(JComponent.java:1029)
        at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
        at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1479)
        at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1410)
        at javax.swing.RepaintManager.paint(RepaintManager.java:1224)
        at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
        at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:785)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
        at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
        at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

3 个答案:

答案 0 :(得分:3)

你正在

IndexOutOfBoundsException异常

来自堆栈跟踪的

。这意味着您正在引用一个大于数组长度的数组索引。

删除行后可能会发生这种情况。您需要确保在删除行时,您会注意到已删除行之后的所有行的索引都将更改。

换句话说,如果你有

0 - row1
1 - row2
2 - row3
3 - row4

如果删除索引1处的行,则表格看起来像

0 - row1
1 - row3< - 注意更改
2 - row4

答案 1 :(得分:0)

对于初学者,请查看1975年的ContactsGUI.java行。这就是抛出异常的地方。查看那里引用的ArrayList。然后,您必须查看确定该列表大小的位置以及如何确定从该列表中访问哪个元素。

如果您使用IDE,请在该行上设置断点并调试应用程序 - 这可能会有很大帮助。

答案 2 :(得分:0)

  

我第一次触发数据更改事件的原因是我想用包含我要删除的行的数据的文本更新JLabel(可能有一种更优雅的方式)。

此功能不应该是TableModel的一部分。调用删除逻辑的按钮应该在调用remove row方法之前保存所需的信息。然后removeRow()代码应该在触发表行删除事件之前从rowData中删除该行。

  

但似乎在我编辑一行后大部分时间都会发生,有一个列排序处于活动状态,然后删除一行

您需要将行视图转换为行模型。我认为代码应该是这样的:

int modelRow = tableConvertRowIndexToModel( selectedRow );
rowData.remove(modelRow); 
fireTableRowsDeleted(modelRow, modelRow);