【问题标题】:I'm getting an Exception in Java Swing, but the program continues to run fine. Should I be worried?我在 Java Swing 中遇到异常,但程序继续运行良好。我应该担心吗?
【发布时间】:2014-02-24 22:45:58
【问题描述】:

我正在使用 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)

我讨厌这个异常,因为它没有指向 my 代码中的任何地方。我知道在此异常之前会发生什么,因为我已经尝试自己解决了一段时间,但是我找不到 ArrayOutOfBoundsError 应该在哪里出现。我相当肯定它与更新 JTable 有关,但该表工作正常。

所以,我要问的是,谁能告诉我为什么会发生这种情况,我是否应该担心,因为程序仍然可以正常工作?

编辑:经过大量测试,我确定我无法在另一个程序中重现此异常。我还发现它发生在随机时间,但总是在调用另一个类中的某个方法之后发生。此调用是从 SwingWorker 的 process() 方法进行的,它所做的只是从 DefaultTableModel 中删除所有行,然后在 for 循环中一次添加一个包含新信息的行。通过打印到控制台,我发现异常将在 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]});
    }

我不知道这是否有帮助,但这是我必须补充的,抱歉。

【问题讨论】:

  • 尽快发布Minimal Complete Example 以获得更好的帮助
  • 消息已清除,您正在尝试访问数组的第 19 个索引,而数组大小为 18。您应该知道数组索引为 0
  • @AdnanAhmadKhan 但它发生在 java.util.Vector 中,而不是 OP 的代码中。
  • @AdnanAhmadKhan:没有直接引用 OP 编写的任何代码行,这使得修复有点困难。
  • 您是从processdone 方法更新用户界面吗?如果不是,那么您就违反了 EDT 合同……是的,您应该担心。

标签: java swing exception swingworker


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2012-11-05
    • 1970-01-01
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-05
    • 1970-01-01
    相关资源
    最近更新 更多