我在 Java Swing 中遇到异常,但程序继续运行良好。我应该担心吗?



我正在使用SwingWorker来更新GUI的某些部分,而且我对使用它们还比较陌生,所以我不确定是什么原因造成的,也不确定它是否重要。基本上,当这个大型流程完成在线收集数据时,SwingWorker告诉JTable使用新信息进行更新。它确实做到了,而且GUI完全按照它应该的方式工作。但是,控制台会打印此异常:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 19 >= 18
at java.util.Vector.elementAt(Vector.java:470)
at javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:649)
at javax.swing.JTable.getValueAt(JTable.java:2720)
at javax.swing.JTable.prepareRenderer(JTable.java:5718)
at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2114)
at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2016)
at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1812)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
at javax.swing.JComponent.paintComponent(JComponent.java:778)
at javax.swing.JComponent.paint(JComponent.java:1054)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JViewport.paint(JViewport.java:725)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5221)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1482)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1413)
at javax.swing.RepaintManager.paint(RepaintManager.java:1206)
at javax.swing.JComponent._paintImmediately(JComponent.java:5169)
at javax.swing.JComponent.paintImmediately(JComponent.java:4980)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:770)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:728)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:677)
at javax.swing.RepaintManager.access$700(RepaintManager.java:59)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1621)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
at java.awt.EventQueue.access$000(EventQueue.java:101)
at java.awt.EventQueue$3.run(EventQueue.java:666)
at java.awt.EventQueue$3.run(EventQueue.java:664)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

我讨厌这个Exception,因为它不指向我的代码中的任何地方。我知道在这个异常之前会发生什么,因为我已经试图自己解决这个问题有一段时间了,但我找不到ArrayOutOfBoundsError可能发生的地方。我很确定这与更新JTable有关,但该表运行良好。

所以,我想问的是,有人能告诉我为什么会发生这种情况吗?我是否应该担心,因为这个程序仍然运行良好?

编辑:经过广泛的测试,我确定我无法在另一个程序中重现这个异常。我还发现它发生在一个随机的时间,但总是在调用另一个类中的某个方法之后。这个调用是从SwingWorker的process()方法进行的,它所做的只是从DefaultTableModel中删除所有行,然后在for循环中添加包含新信息的行,每次一行。通过打印到控制台,我发现Exception将在for循环开始之前、结束之后或在for循环期间的某个随机时间抛出。我已经运行了整个过程,没有出现异常。这是有问题的方法的通用版本:

for(int i = table.getRowCount() - 1; i >= 0; i--)
model.removeRow(i);
for(InfoObject o : listOfInfoObjects) {
int[] stats = o.getStats();
model.addRow(new Object[] {o.getName(),
stats[0], stats[1], stats[2], stats[3], stats[4], stats[5]});
}

我不知道这是否有帮助,但我只想补充一点,对不起。

最可能的原因是程序中线程使用不当。Swing运行一个名为Event Dispatch线程的线程,所有对控件、布局等的更改都必须在该线程上完成。

您可以使用SwingUtilties.invokeLater在EDT上执行代码。

http://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html

相关内容

最新更新