2

私の問題は単純ですが、コードは複雑で、答えを見つけるのは簡単ではありません。そのため、助けを求めています。

私はマルチスレッドアプリケーションをプログラミングしています.これがどのように機能するかです:

1) 1 つのスレッドがファイルを読み取り、テキストファイルから情報を解析しています (500 ミリ秒ごとにファイルの最後に到達しようとします)。

2) 関連する情報が見つかると、スレッドはそれを保存し、オブザーバーであるコントローラーに通知します。

3)コントローラーに通知されると、ユーザーに表示したい情報を更新する他のスレッド(GUI)に通知します。

GUI があまりにも頻繁に更新されるため、私が呼び出すrevalide()validate()、または例外がある場合を除きます。repaint()

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を試行する別のスレッドを実行することを考えましたが、より良い代替手段があるかもしれません。呼び出す前にGUIスレッドを停止してから再開するなど、心配する必要があることはありrevalidate()ますか?


はい、パネルからコンポーネント (JLabels) を削除して、新しいデータのコンポーネントに置き換えます。私はあなたが言ったことを試してみます。

ところで、invokelater と start like another thread に大きな違いはありますか?


解決 :

次のようなメソッドを作成しました。

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

1 に答える 1

2

例外は、EDTの外部でGUIに何かが起こって、すべてが台無しになっているように思えます。具体的には、GUIが再描画しようとしているときに、コンポーネントが削除されたようです。

コンポーネントを追加/削除するコードをRunnable渡してSwingUtilities.invokeLater()、GUIを変更するすべてのものが同期されていることを確認してください。

于 2011-02-13T00:56:15.710 に答える