刷新GUI时线程中的异常

时间:2011-02-13 00:32:51

标签: java swing validation repaint

我的问题很简单,代码很复杂,答案也不容易找到,所以我正在寻求帮助。

我正在编写多线程应用程序,以下是它的工作原理:

1)一个线程正在读取文件并从文本文件中解析信息(每500毫秒尝试到达文件的末尾)

2)当找到相关信息时,线程将其存储并通知作为观察者的控制器

3)当通知控制器时,它通知另一个线程(GUI)更新我想向用户显示的信息。

除非我调用revalide()validate()repaint(),否则会出现异常,因为GUI经常更新。

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: No such child: 7
        at java.awt.Container.getComponent(Container.java:323)
        at javax.swing.JComponent.rectangleIsObscured(JComponent.java:4393)
        at javax.swing.JComponent.paint(JComponent.java:1052)
        at javax.swing.JComponent.paintToOffscreen(JComponent.java:5206)
        at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1493)
        at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1424)
        at javax.swing.RepaintManager.paint(RepaintManager.java:1217)
        at javax.swing.JComponent._paintImmediately(JComponent.java:5154)
        at javax.swing.JComponent.paintImmediately(JComponent.java:4964)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:781)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:739)
        at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:688)
        at javax.swing.RepaintManager.access$700(RepaintManager.java:59)
        at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1632)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:660)
        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)

我考虑过运行另一个线程,每500毫秒可能尝试revalidate() GUI,但可能有更好的选择。 有什么我应该担心的,比如在我调用revalidate()之前停止GUI线程然后恢复它或类似的东西?


是的,我确实从面板中删除了组件(JLabel),用具有新数据的组件替换它们。我会试试你说的话。

顺便说一下,invokelater和另一个线程之间有很大的区别吗?


解决方案:

我创建了一个如下所示的方法:

protected void updateGUI(final Param param1, final Param param2){
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            //write your code
            param1.validate();
            param1.repaint();
        }
    });

1 个答案:

答案 0 :(得分:2)

在我看来,EDT之外的GUI发生了一些例外情况,这会让所有人感到困惑:更具体地说,当GUI想要重新绘制它时,组件似乎被移除了。

尝试将添加/删除组件的代码作为Runnable传递给SwingUtilities.invokeLater(),以确保以任何方式更改GUI的所有内容都已同步。