3

我開發了一個用於創建和提取存檔的Java應用程序 - 例如WinRAR。您可以使用多線程同時創建多個存檔。最近,我想在創建檔案的過程中以JProgressBar的形式在每次創建時在新的JFrame中添加信息狀態。在多任務應用程序中管理GUI和EDT

但我的問題是在新的狀態框架和創建存檔的線程中生成信息。這就是爲什麼我在歸檔線程中創建JFrame來更新當前的進度條。

但是就像我可以在不同的信息源和你的答案/評論中閱讀它,這是針對Java Swing和性能;我無法在EDT的其他地方創建擺動物體。

但是,那麼,我該如何解決我的問題?如何建立我的檔案的寫入和其狀態JFrame(使用JProgressBar)之間的通信?


編輯:

我實現的SwingWorker來管理我的應用程序的GUI。現在完成了,我還有其他問題:

使用SwingWorker時,如何在狀態爲Frame的按鈕的事件上對後臺任務執行操作? (實施例:暫停壓縮或停止它。)在一個JDialog

回答

5

正如其他人所建議的,最好的方法是使用SwingWorker

SwingWorker性能可聽和聽衆總是堪稱EDT,因此,你可以這樣做:

public class ArchivingWorker extends SwingWorker<Void, Void> { 
    JProgressBar progressBar = null; 
    // Other members here... 
    ... 

    public ArchivingWorker(...) { 
     // Any specific initialization here (in EDT) 
     addPropertyChangeListener(new PropertyChangeListener() { 
      @Override void propertyChange(PropertyChangeEvent e) { 
       if ( "state".equals(e.getPropertyName()) 
        && e.getNewValue() == StateValue.STARTED) { 
        // Background thread has just started, show a progress dialog here 
        progressBar = new JProgressBar(); 
        ... 
       } 
       else if ("progress".equals(e.getPropertyName())) { 
        // Update progress bar here with e.getNewValue() 
        ... 
       } 
      } 
     }); 
    } 

    @Override protected Void doInBackground() { 
     // Archiving process here and update progress from time to time 
     setProgress(progress); 

     return null; 
    } 

    @Override protected void done() { 
     // Ensure that archiving process worked correctly (no exception) 
     try { 
      get(); 
     } catch (Exception e) { 
      // Handle exception (user feedback or whatever) 
     } finally { 
      // Close progress dialog 
      ... 
     } 
    } 
} 

然後你可以使用ArchivingWorker,你需要它:

ArchivngWorker worker = new ArchivingWorker(...); 
worker.execute(); 
+0

+1如果你對Swing有最深的瞭解 – mKorbel

+0

我真的忘了問你,你知道一些關於http://stackoverflow.com/questions/7053865/cant-get-arrayindexoutofboundsexception-from-future-and-swingworker-如果線程 – mKorbel

+0

@mKorbel不,但我會學習。我想它談論的是擺動工作者的配合。 – damson

5
  1. PUT和顯示JProgressBar,並且不產生新的Top-Level Container。創建一次,並重新使用該

  2. 朗定時和重碼會更好重定向到後臺任務

  3. 你可以進步JProgressBar從後臺任務只移動

    • 如果與GUI相關的代碼在EDT上完成更多Concurrency in Swing

    • 並且有兩種正確的方法可以做到這一點

      • 使用SwingWorker

      • Runnable#Thread但GUI rellated代碼必須被包裹成invokeLater()

+1

@annonymous_up -voter謝謝,10k !!! – mKorbel

+0

我想我理解揮杆表現的一致性。我開始用SwingUtilities(invokeLater/isEventDispatchThread)開發一個新的實現,但代碼太重,狀態GUI有一些bug和凍結。我將嘗試與SwingWorker。 – damson

+0

最簡單和完全可管理的是通過使用Runnable#線程 – mKorbel

1

@mKorbel提供的答案是好的,但也確實是不需要使用另一個頂級容器(例如,一個JDialog)來顯示進度條。相反,您可以使用JFrame實例的Glass Pane

+0

感謝您的答案。 關於頂級容器,我沒有任何使用它的選擇,因爲JDialog全面關注應用程序,多任務變得毫無用處。 (我不知道我是否可以理解;告訴我,如果我不知道) – damson

+0

@damson,沒有......沒有什麼意義。 – mrkhrts

相關問題