1

少し問題があります。今は小さな Java プロジェクトに取り組まなければなりません。Button イベント ハンドラーからいくつかのスレッドを実行しようとしています。次に、最後のスレッドが UI の TextArea を更新する必要があります。スレッドは計算作業を行っています。最も重要な部分は、UI woks をうまくすることです。UI をフリーズしたくありません。もちろん、UI の TextArea を定期的に他のスレッドの 1 つ (UI のものではない) から更新したいと考えています。だからここに私のコードの一部があります:

Button のイベント ハンドラー内で、次の 4 つのスレッドを開始しています。

Thread generate = new CombinaMaker();
generate.run();

Thread forward = new TranslateForward();
forward.run();

Thread backward = new TranslateBackward();
backward.run();

Thread refresh = new Refresher();
refresh.run();

スレッドを同時に動作させたい。Refresher スレッドは、定期的に UI TextArea コンポーネントを更新する必要があります。

したがって、Refresher スレッドから UI を更新する方法は次のとおりです。

public static void updateProgress() 
{
    SwingUtilities.invokeLater(new Runnable() 
    {   
         public void run() 
         {
             //HERE
             //I have a loop that have to be looping at every 500 ms
         }
     }
}

私の質問は次のとおりです。これをリンクする必要がありますか? 私はシンプルで効果的である必要があります。このループは、アプリケーションが動作している限りループしているに違いないため、私を悲しくさせます。これがUIをフリーズさせる理由でしょうか?どこかで大きな間違いを犯していることはわかっていますが、現時点ではそれを一人で見つけることはできません。簡単な解決策を提案できるかもしれません。そして最後の考え - 最初の 4 つのスレッド: UI をフリーズせずに、それらを「同時に」開始したいと考えています。その方法(イベントハンドラーからこのように開始する...)は正しいですか、それとももっと良いのでしょうか?たくさんの友達に感謝します!

PS。「リフレッシャー」スレッドを使用して UI を更新するのが難しい場合は、妥協案の準備ができています - 彼自身のスレッド (UI スレッド) を介して UI を更新します。しかし、この場合、UI のフリーズを回避するために、何らかの「タイム シューティング メカニズム」を使用する必要があるかもしれません。あなたは何を考えていますか?

4

4 に答える 4

3

主な問題はアルゴリズムです。それ以外の

SwingUtilities.invokeLater(new Runnable() {   
    public void run() {
        //HERE
        //I have a loop that have to be looping at every 500 ms
    }
}

あなたが持っている必要があります

// HERE
// I have a loop that have to be looping at every 500 ms
// and when something must be updated in the GUI:
SwingUtilities.invokeLater(new Runnable() {   
    public void run() {
        // update the GUI as fast as possible
    }
});

すなわち

while (true) {
    Thread.sleep(500L);
    String update = getUpdate();
    SwingUtilities.invokeLater(new Runnable() {   
        public void run() {
            textArea.append(update);
        }
    });
}

に渡されるランナブルSwingUtilities.invokeLater()は、イベントディスパッチスレッドで実行されます。長時間実行されるタスクを実行してはなりません。無限にループすることは、非常に長時間実行されるタスクです。

于 2012-10-16T21:38:33.563 に答える
2

invokeAndDoLaterに渡すランナブルをループさせたくありません。例については、これを参照してください:http ://www.javamex.com/tutorials/threads/invokelater.shtml

于 2012-10-16T21:38:10.693 に答える
1

UIをフリーズしたくないし、もちろん

UIをフリーズしたくないと言ってください。残念ながら

UIのTextAreaを他のスレッドの1つから定期的に更新したい

オプションではありません。Swingコンポーネントの更新は、UIスレッド(イベントディスパッチスレッド)で実行する必要があります。幸い、Swingには、UIを定期的に更新するための組み込みクラスであるjavax.swing.Timerクラスがあります。はTimerバックグラウンドで実行され、イベントディスパッチスレッドで実行されるため、このタスクに最適です。

于 2012-10-16T21:41:30.333 に答える
1

SwingUtilities.invokeLater は、実行時間の長いスレッドを呼び出すようには設計されていません。あなたの問題に対する1つの解決策は、これかもしれませ

ループのネストと SwingUtilities.invokeLater 呼び出しを逆にすることもできますが、これが実現可能かどうかはコードの残りの部分に依存します。

do {
    // Sleep and other stuff
    SwingUtilities.invokeLater(new Runnable() {
        public void run()  {
        // Update UI
        }
    });
} while(...);
于 2012-10-16T21:32:09.830 に答える