2010-11-23 15 views
13

は、私は次のコードを持って言う:SwingWorkerのdoInBackground()メソッドを待つ方法を教えてください。

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()を使用すべきであることを知っていますが、それを呼び出すスレッドが必要です。join()からdoInBackground()のスレッドを取得する方法がわかりません。助けてくれてありがとう。


編集:ありがとうございます。残念なことに、get()などは、この問題をかなり解決していません。実際のコードでは、SwingWorkerには、バックグラウンドスレッドの実行中にGUIウィンドウを更新するオーバーライドされたprocess()関数もあります。 get()doInBackgroundの後に印刷されるのを「完了」しますが、GUIは更新されません。これを反映するようにサンプルコードを更新しましたが、現在はコンパイルされません。

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

答えて

11

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

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

+0

いいえ、私は 'done()'を使って動作させました。ご協力いただきありがとうございます。 – Max

+1

将来のgooglerのための注意:これは、SwingWorkerがキャンセルされたときに本当に役に立ちません。 'done()'は 'doInBackground()'が完了する前に実行できます。 :-(http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6826514 http:// stackoverflow。com/questions/6204141/swingworker-when-called-done-method- – kmort

9

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

のJavadocから:

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

あなたのコードは、次にようになります。それはあなたがisDone()を呼び出すことによってテストすることができた、完了するまで一般に

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

を、あなたはSwingWorker上に保持する必要がありますそれ。それ以外の場合は、get()を呼び出して待ちます。

5

doInBackground()が完了したときに呼び出されるdone()メソッドをオーバーライドすることができます。 done()メソッドはEDTで呼び出されます。だから、のようなもの:行って内部のget()メソッドを呼び出すと

@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 
    } 
} 

はdoInBackground中にスローされた例外を取り戻すのに役立ちますので、私は非常にお勧め。 SwingWorkerは、CallableとFutureを内部的に使用してバックグラウンドスレッドを管理します。これは、結合/利回りアプローチを試す代わりに読み上げたい場合があります。

+0

これをColin Dの回答にコメントしておくべきでしょうか。 – Jim

+0

get()を使用して例外が発生する点 – HaveAGuess

関連する問題