2011-03-02 72 views
2

首先,我一直在使用Java的Concurrency軟件包,但是我發現了一個問題,我被卡住了。我想要和應用程序和應用程序可以有一個SplashScreen與狀態欄和加載其他數據。所以我決定使用SwingUtilities.invokeAndWait(call the splash component here)SplashScreen然後出現JProgressBar並運行一組線程。但我似乎無法很好地處理事情。我已經看過SwingWorker並嘗試使用它來達到這個目的,但是線程剛剛返回。這裏有一些僞代碼。和我試圖達到的要點。帶可更新JProgressBar的Java Swing線程

  • 有具有SplashScreen同時加載信息
  • 能夠根據SplashScreen
  • 運行多個線程暫停的應用程序有SplashScreen更新,能夠尚未退出的進度條,直到所有線程都完成。

啓動閃屏

try { 
    SwingUtilities.invokeAndWait(SplashScreen); 
} catch (InterruptedException e) { 
} catch (InvocationTargetException e) { } 

閃屏建設

SplashScreen extends JFrame implements Runnable{ 

    public void run() { 
     //run threads 
     //while updating status bar 
    } 
} 

我已經嘗試了很多事情,包括SwingWorkers,使用CountDownLatch的,和其他線程。 CountDownLatch實際上以我想要處理的方式工作,但我無法更新GUI。當使用SwingWorkers時,invokeAndWait基本上無效(這是它們的用途),或者即使使用PropertyChangedListener也不會更新GUI。如果其他人有一些想法,聽到他們會很高興。提前致謝。

我實際上已經準備好發佈更好的代碼來幫助並找到我的解決方案。我感謝所有幫助過的人。

+1

如果您可以創建併發布[SSCCE](http://SSCCE.org),則您的問題可能會更快更準確地得到解決。 – 2011-03-02 05:49:31

+0

對不起,我正在上牀睡覺,因爲我張貼了,我所有的都是非常醜陋的代碼發佈,所以我希望能得到這個想法,如果下面的答案不適合我,我會發布一些真實的代碼。感謝您的建議。 – ars265 2011-03-02 13:15:02

回答

0

無需調用invokeAndWait中的框架,但應該像這樣更新進度欄狀態。

try { 
    SwingUtilities.invokeAndWait(new Runnable() { 
    public void run() { 
//update state of the progress bar here 
    } 
    }); 
} catch (InterruptedException e) { 
} catch (InvocationTargetException e) { } 
+0

謝謝,我會試試看看是否有幫助。 – ars265 2011-03-02 13:13:04

+0

我無法得到這與線程或SwingWorkers一起工作,我用一些更好的代碼更新我的問題。感謝您一直以來的幫助。 – ars265 2011-03-03 17:31:47

5

要在後臺運行一系列操作並報告進度,請使用SwingWorker

方法background做後臺處理。
使用publish方法發佈定期狀態更新。
替代處理更新的process方法(process始終在EDT上執行)。

progressBar = new JProgressBar(); 
sw = new SwingWorker<Boolean,Integer>() { 
    protected Boolean doInBackground() throws Exception { 
     // If any of the operations fail, return false to notify done() 
     // Do thing 1 
     publish(25); // 25% done 
     // Do thing 2 
     publish(50); // 50% done 
     // Do thing 3 
     publish(75); // 75% done 
     // Do thing 4 
     return true; 
    } 
    protected void process(List<Integer> chunks) { 
     for (Integer i : chunks) 
      progressBar.setValue(i); 
    } 
    protected void done() { 
     try { 
      boolean b = get(); 
      if (b) 
       progressBar.setValue(100); // 100% done 
      else 
       // Notify the user processing failed 
     } 
     catch (InterruptedException ex) { 
       // Notify the user processing was interrupted 
     } 
     catch (ExecutionException ex) { 
       // Notify the user processing raised an exception 
     } 
    } 
}; 

附錄:

這可以擴展到多個任務,它只是需要改變你的做法是如何設置的進度條。下面是想到的:

有一個完成計數器數組,每個任務一個。

int[] completions = new int[numTasks]; 
Arrays.fill(completions,0); 

啓動SwingWorkers,每個都傳遞一個索引號。然後processdone方法調用這樣的更新整體進度條。

void update(int index, int percComplete) { 
    completions[index] = percComplete; 
    int total = 0; 
    for(int comp: completions) 
     total += comp/numTasks; 
    overallPB.setValue(total); 
} 

(可選)顯示每個任務的JProgressBar。

附錄2:

如果任務完成時間變化(例如,緩存命中VS高速緩存未命中),你可能需要調查ProgressMonitor。這是一個進度對話框,只有當任務需要超過一些(可配置的,默認的500ms)時間時纔會出現。

+0

這似乎並不奏效我需要多個swing工作人員,他們仍然繼續執行下一個代碼,這就是爲什麼我提到invokeAndWait()方法,因爲我需要它等待,我需要多個SwingWorkers運行,我不想繼續,直到所有的工人完成。 – ars265 2011-03-03 17:30:35