13

次のコードがあるとします。

import java.lang.InterruptedException;
import javax.swing.SwingWorker;

public class Test
{
    private JDialog window;

    public Test
    {
        // instantiate window
    }

    private class Task extends SwingWorker<Void, Void>
    {
        public Void doInBackground()
        {
            try { Thread.currentThread().sleep(5000); }
            catch(InterruptedException e) {}
            return null;
        }
    }

    public void doTask()
    {
        Task task = new Task();
        task.execute();
    }

    protected void process()
    {
        // update various GUI components here
    }

    public static void main(String args[])
    {
        Test t = new Test();
        t.doTask();
        System.out.println("done");
    }
}

「完了」を出力する前に完了するまで待つ必要がありますがt.doTask()、正確な方法がわかりません。おそらくここで使用する必要があることはわかっていますが、それを呼び出すスレッドが必要であり、呼び出す必要がある場所から のスレッドjoin()を取得する方法がわかりません。助けてくれてありがとう。doInBackground()join()


編集:回答ありがとうございます。残念ながら、get()などは問題を完全には解決しません。私の実際のコードでは、SwingWorker にはprocess()、バックグラウンド スレッドの実行中に GUI ウィンドウを更新するオーバーライドされた関数もあります。 get()'done' が後まで出力されないようdoInBackgroundにしますが、GUI は更新されません。これを反映するようにサンプル コードを更新しましたが、もちろんコンパイルされません。

一度だけ印刷するように「完了」する方法はありdoInBackgroundますか? GUI 更新コードと 'done' ステートメントは同じスレッドにありますか? 新しいスレッドを作成する必要がありますか?

4

4 に答える 4

11

SwingWorker通常、 がバックグラウンド作業を完了した後に実行する必要があることはすべて、その中のdone()メソッドをオーバーライドすることによって行われます。このメソッドは、完了後に Swing イベント スレッドで呼び出され、GUI を更新したり、何かを出力したりできます。完了するまでブロックする必要がある場合は、 を呼び出すことができますget()

注意。get()メソッド内で呼び出すdone()とすぐに結果が返されるため、UI 作業がブロックされることを心配する必要はありません。

于 2010-11-23T22:37:08.557 に答える
9

を呼び出すget()と、SwingWorkerがブロックされます。

Javadoc から:

T get() 
      Waits if necessary for the computation to complete, 
      and then retrieves its result.

コードは次のようになります。

public static void main(String args[])
{
    Test t = new Test();
    t.doTask();
    t.get();  // Will block
    System.out.println("done");
}
于 2010-11-23T22:34:30.607 に答える
5

doInBackground() が完了すると呼び出される done() メソッドをオーバーライドできます。done() メソッドは EDT で呼び出されます。次のようなものです:

@Override
protected void done() {
  try {
    super.get();

    System.out.println("done");
    //can call other gui update code here
  } catch (Throwable t) {
    //do something with the exception
  }
}

done 内で get() メソッドを呼び出すと、doInBackground 中にスローされた例外を取り戻すのに役立つため、強くお勧めします。SwingWorker は内部で Callable とFutureを使用してバックグラウンド スレッドを管理します。これについては、join/yield アプローチを試す代わりに読みたいと思うかもしれません。

于 2010-11-30T18:41:30.760 に答える
0

SwingWorker一般に、終了するまで保持する必要があります。これは、呼び出しisDone()てテストできます。それ以外の場合は、呼び出しget()て待機させます。

于 2010-11-23T22:35:50.153 に答える