2013-03-30 192 views
1

我有一些代碼在單獨的線程中執行下載,創建的目的是爲了讓JFrame GUI在下載過程中繼續更新。但是,當我使用Thread.join()時,目的完全失敗,因爲它導致GUI停止更新。我需要一種方法來等待線程完成並仍然更新GUI。等待Java中的線程完成

+5

檢查[SwingWorker類](http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html) – m0skit0

回答

4

您可以讓下載的任務也將事件發送到GUI。

例如:

Runnable task = new Runnable() { 
    public void run() { 
     // do your download 

     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      // call some method to tell the GUI that the download finished. 
     } 
     }); 
    } 
}; 

,然後運行它,要麼使用一個Executor(優選方法)或原紗:

executor.execute(task); 

new Thread(task).start(); 

正如在comme中指出的那樣nts,您通常會使用SwingWorker來做這種事情,但您也可以使用上述的手動方法。

的SwingWorker提供了一個doInBackground方法,你要堅持你的下載邏輯,一個done方法,你會堅持代碼來通知下載完成的GUI和get方法得到的doInBackground結果(如果有一個)。

例如,

class Downloader extends SwingWorker<Object, Object> { 
    @Override 
    public Object doInBackground() { 
     return doDownload(); 
    } 

    @Override 
    protected void done() { 
     try { 
     frame.downloadDone(get()); 
     } catch (Exception ignore) { 
     } 
    } 
} 

(new Downloader()).execute(); 
+0

偉大的答案,但第一解決方案只會在線程完成後更新GUI,而我希望在下載開始時這樣做。我已經嘗試了第二種解決方案,但它非常混亂,並且似乎在下載完成之後才起作用。 – caseif

+0

在撥打電話開始下載之前,您不能更新GUI嗎? –

+0

我試過了,但由於某種原因,它沒有更新。下面是我使用的代碼: '如果(!lwjglZip.exists()||更新)//這兩個都TRUE' '進度= 「下載LWJGL」;'' 重繪();'' //執行線程' 進度變量在paintComponent方法中用作應繪製的字符串。 – caseif