2010-12-20 206 views
0

这是我的第一个问题。首先,我是Java新手,仍然很难理解事件。为了展示一些自定义工具提示(来自不同列的数据的组合),我使用了一个自定义模型来扩展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) 

回答

0

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

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

,但现在看来,这恰好大部分的时间后,我编辑成一排,有排序活跃一列,然后删除行

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

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

我一直在做模型行转换的视图,但您的其他提示我认为解决了我的问题。通过保存数据,删除行并发起更改,我似乎没有得到错误。我认为这是原因:在重新绘制表格时,我也删除了一行。多谢。 – Max 2010-12-20 14:57:57

3

您从堆栈跟踪获取

IndexOutOfBoundsException异常

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

这可能是在您删除一行后发生的。您需要确保删除行时,您注意到删除行后面的所有行的索引都会更改。

换句话说,如果有

0 - ROW1
1 - ROW2
2 - ROW3
3 - ROW4

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

0 - ROW1
1 - ROW3 < - 注意变化
2 - ROW4

+0

你是不是指“0 - row1 1 - row3 2 - row4”? – 2010-12-20 05:19:26

+0

@jean,当然。该死的。 thanx指出了这一点。 – hvgotcodes 2010-12-20 14:27:16

+0

是的,我明白的错误,我无法弄清楚什么是调用getValueAt方法,但我现在很确定它是:table重绘,因为我解雇了数据的变化,并在我删除行后。但是你的例子让我意识到了另外一件事:当我像你的例子那样在“中间”删除一行时,错误从未发生过。但总是当它是模型中的最后一行时(因此导致以超出边界的索引调用getValueAt())。通过删除不同的行,列表将被重新编制索引并查找“已删除”索引所在的值。 Thx帮助球员。 – Max 2010-12-20 15:06:02

0

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

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

+0

我试图设置一个断点,但是在那一点上,我只能看到该方法即将尝试使用超出限制的索引来获取值。 Camickr让我走上了正确的轨道:发起改变而不是做出改变是个坏主意。 – Max 2010-12-20 14:59:59

相关问题