2014-10-06 71 views
0

在我的應用程序中,我有一個主框架窗口GUI,它啓動executor服務中的任務。糾正設計以防止JFrame中的黑屏問題

提交的任務generates輸出和存儲in a file on Disk

o/p一旦生成GUI(觀察者)被通知生成的o/p。

這裏的問題是我在主框架內部保持一個等待循環,並且一旦收到通知,主面板就會在主框架上重新繪製。

對於小任務,這可以很好地工作,但隨着線程任務的大小增加。等待循環時間增加,GUI主窗口變黑,直到計算完成。

你能幫我糾正一下設計嗎?另外在這種情況下,SwingWorker線程如何能夠提供幫助。

回答

3

等待循環時間增加,GUI主窗口變黑,直到計算完成。

然後,您長時間運行的任務正在執行事件調度線程(EDT),這會阻止GUI重新繪製自己。您需要在單獨的線程中執行長時間運行的任務。 SwingWorker是一個獨立的線程,它具有一個API,它還允許您根據需要在EDT上執行代碼,例如代碼執行完成或中間結果。

請參閱Concurrency的Swing教程中的部分了解更多信息。您始終可以在論壇中搜索使用SwingWorker的示例。

+0

Ahem,OP明確指出「我在主框架內部保留一個等待循環」。正如OP在第一句中明確指出的那樣,這就是保持美國東部時間繁忙,而任務在執行程序線程上運行。這個答案有正確的精神,但似乎你沒有仔細閱讀這個問題。另外,'SwingWorker'不是**完全獨立的線程,它們也使用執行器服務。 – Ordous 2014-10-06 15:02:23

+0

@Ordous,'另外,SwingWorker不是一個完全獨立的線程,它們也使用執行程序服務 - 實現無關緊要。重要的部分是後臺任務在單獨的線程上執行,而不是EDT。我的回答是,你不應該阻止/等待美國東部時間,因爲GUI無法響應事件並進行重新繪製。 – camickr 2014-10-06 16:11:34

2

1) 等待循環是所有GUI的禍根。它們可以在你產生的其他線程中執行,在Executors中很棘手(因爲它們有時對線程數量有限制,取決於你使用的線程數量),並且在EDT上完全不存在問題。這就是你的「黑屏」的原因

2) 而不是使用自定義(我假設它是自定義的)信號協議和等待循環,你可以使用Swing中的一個工具類。例如,SwingUtilities有幾個不錯的方法 - invokeLaterinvokeAndWait,它們採用Runnable,並儘快在EDT上執行它。使用這個而不是你所擁有的信號將允許你不阻止EDT並使GUI響應。

3) 如果你真的想使用SwingWorker你可能想看看它的文檔。它本質上是一種完成後臺任務並向EDT報告進度或完成情況/結果的方式。目前它使用帶有2個後臺線程的ExecutorService,因此在其上執行很多長時間運行的任務並不是一個好主意(它們會彼此阻塞)。當創建一個SwingWorker你會指定要運行在後臺的方法,該方法對EDT跑出當你在中間結果是可用的,並且該方法對EDT跑出完成無論是成功還是錯誤。

4) 這並不涉及到手頭的問題,但如果您遇到了需要EDT中的等待循環並且無法使用其他設計或技術避免它的情況,則始終可以切換到使用一個Timer。它可以設置爲每隔x毫秒調用一次,而不會阻塞EDT,並在您滿足某些條件時關閉。

+0

因爲我的等待循環取決於線程產生的第一個輸出,所以我認爲第四個建議會有幫助。謝謝 :) – 2014-10-07 06:01:43