2013-03-30 141 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