2

私は Swing の初心者で、現在 NetBeans で簡単な GUI アプリケーションを開発しようとしています。

アプリケーションによって実行されている現在のアクションを TextArea に書き込むために、ある種の GUI ロギング システムを作成したいと考えています。

簡単な例として、「開始」ボタンと TextArea の 2 つのオブジェクトのみを含む JFrame フォームを作成しました。

「開始」ボタンが押されると、実行が完了するまでに時間がかかる (たとえば 10 秒) 必要があるある種の長いメソッドが呼び出されます。このメソッドの実行中に、これを使用して TextArea にテキストを追加したいと考えています。長いメソッド(もちろん、TextAreaをすぐに更新したい)。

私の問題は、それを行う適切な方法が見つからないことです。とにかく、「開始」ボタンを押すと、アプリケーションが 10 秒間フリーズし、TextArea が必要なように更新されませんでした。メソッドが終了したときにのみ、TextArea が更新されます。

サンプルコードは次のとおりです。

private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {
    try {
        for (int i = 0; i < 10; i++) {
           textArea.setText(i + "\n");
            Thread.sleep(1000);
        }
    } catch (Exception e) {}
}

この例では、ボタンをクリックすると、次の 10 秒間、次のように TextArea に新しい行が 1 秒ごとに追加されることが期待されます。

1

2

3

4

...

しかし、このコードから得られる実際の結果は、アプリケーションが 10 秒間フリーズし、最終的に TextArea が更新され、数字の 9 だけが表示されるということです。

主にSwingUtilities.invokeLaterおよびSwingWorkerメソッドを使用して、これを正しく行うためのさまざまな方法を試しましたが、どれもうまくいきませんでした。

それを行う正しい方法を見つけるための助けをいただければ幸いです。

4

3 に答える 3

8

1.常にUI 作業を UI スレッドで維持し、非 UI 作業を非 UI スレッドで維持します。

2. Java GUI アプリケーションでは、メソッドmain()は長生きしませんEvent Dispatcher Thread

3. GUI 作業専用の GUI スレッドである EDT スレッドを常に保持します。

例えば:

public static void main(String[] args){


        EventQueue.invokeLater(new Runnable(){

              public void run(){

                myframe.setVisible(true);

             }

         }

  }

4.時間がかかるメソッドを処理する別のスレッドを作成します。Non-UI

5. Java に特別に導入されたThreadまたは を使用して、UI スレッドと非 UI スレッドを同期することができます。SwingWorker

于 2012-08-05T15:43:47.960 に答える
6

他の回答で述べたように、あなたは使いたいと思うでしょうSwingWorker-それを読むことをお勧めします.これは信じられないほど便利なツールです. この実装により、サンプルで探しているものが得られるはずです。

ボタンのアクション:

button.addActionListener(new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent arg0) {
        new Worker().execute();
    }
});

あなたのスイングワーカー:

public class Worker extends SwingWorker<String, String>{

    @Override
    protected String doInBackground() throws Exception {
        //This is what's called in the .execute method
        for(int i = 0; i < 10; i++){
            //This sends the results to the .process method
            publish(String.valueOf(i));
            Thread.sleep(1000);
        }
        return null;
    }

    protected void process(List<String> item) {
        //This updates the UI
        textArea.append(item + "\n");
    }
}
于 2012-08-06T04:31:21.777 に答える
3

javax.swing.Timerクラスを使用します。詳細については、「スイング タイマーの使用方法」を参照してください。

于 2012-08-05T15:34:30.923 に答える