2010-08-12 57 views
6

這是針對揮杆專家的。我在這個問題上花費了相當多的時間,所以這需要我用幾行來解釋這個問題。來自EDT問題的Java swing進度條

我有一個獨立的java swing應用程序(java 6)。在我的應用程序中,我有一個帶有單選按鈕組的框架。我有一個單一的動作鏈接到組中的所有按鈕。該操作檢查哪些單選按鈕被選中並執行一些工作。 「工作」涉及到一些背景計算,以及在我的應用程序中的另外兩幅畫。後臺計算是多線程的。

我想在用戶選擇其中一個單選按鈕時顯示一個進度條。 但是,當選擇單選按鈕時,在單選按鈕的動作發生時,進度條從不出現。我試過jdialog類型的進度條,玻璃窗格等等,直到「工作」完成才顯示出來。這似乎是因爲Swing沒有完成繪製單選按鈕,直到相應動作中的「工作」完成。而且由於EDT一次只能處理一件事情,因此不會顯示進度條對話框(或玻璃窗格)。

然後我嘗試使用SwingWorker來完成所有這些「工作」。啓動進度條(或激活玻璃窗格),啓動SwingWorker並關閉SwingWorker的done()方法中的進度條(或取消激活玻璃窗格)。這似乎可以使進度條看起來很好,但作爲「作品」一部分的作品有時並未完成,給我留下了一些繪畫工件(paintComponent方法非常複雜,因此不想在此處重現)。如果我調整窗口大小,工件消失。事實上,如果我使用擴展Thread而不是SwingWorker的類,則會發生這種情況。這完全是因爲Swing不是線程安全的,而且我正嘗試從EDT以外的線程執行GUI工作。我明白那一部分。

我該怎麼辦? 「工作」大約需要30秒,而且如果沒有向用戶顯示程序正在工作的某種跡象,這似乎就太長了。我也嘗試將光標更改爲等待光標,並遇到與上述相同的問題。我唯一能做的就是禁用該框架,並將該框架的標題設置爲「正在工作...」之類的文本。

以前有人看到過這個問題嗎?

回答

4

我認爲你是正確的做SwingWorker線程的工作,但你不應該試圖在那裏做你的畫。

我會傾向於:

  • 擁有的ActionListener秀()的進度條,掀起那麼SwingWorker的退出

  • 有工作線程做的工作,並定期調用在進度條組件上重畫()(這保證是線程安全的)

  • 進度條有它自己的paintComponent(它會自動在EDT上調用)。如果有必要,這可以讀取由工作線程更新的一些變量以測量進度

  • 當工作線程完成時,讓它調用invokeLater()在EDT上運行最終關閉函數,這將隱藏進度條和做任何其他GUI相關的清理/顯示完成消息給用戶等

+0

如何確保EDT在SwingWorker線程的工作完成之前不會執行任何其他繪畫? 可以在背景中完成的工作必須在我的框架再次繪製之前完成。 – Anu 2010-08-13 19:41:57

+0

謝謝!我得到了這個工作。 – Anu 2010-08-13 20:31:29

4

當你將作品從EDT搬到擺動工作人員(這是正確的事情)時,聽起來像工作和繪畫都被搬到了擺動工作人員身上。這幅畫仍然應該在美國東部時間發生。您可以通過使用SwingUtilities.invokeLater來調用來自後臺線程的重繪或使用SwingWorker.publish(V...)來實現此目的,該工具將從工作線程接收通知,並通過SwingWorker.process(V...)模板方法(您可以覆蓋)在EDT上使其可用。您的覆蓋可以通過重新繪製屏幕的一部分,更新進度或根據需要採取其他適當的操作來處理中間通知。在這裏完成的任何UI更改都將可見,而無需等待剩下的工作完成。

+0

謝謝,我Mikera的解決方案的工作,但你對已經移動了畫到EDT評論也刺激了我改變了事情! – Anu 2010-08-13 20:32:16

+0

我認爲在工作線程上使用SwingWorker.publish()是一種可行的方法。 – keuleJ 2010-10-18 19:19:03