java中進度條不能更新問題的研究

爲什麼進度條在事件處理過程中不更新,而是在完成後,從0%調到100%?
分兩種情況:
1)在AWT事件線程中執行的操作
當應用程序在事件線程中執行長時間的操作時,會阻塞正常的AWT事件處理,因此阻止了重繪操作的發生。這同常會在下列情況下發生:應用程序響應一個來自用戶界面的請求時,在連接到一個按鈕或其他GUI組件的事件處理程序中執行任務,任務的內容可能會需要較長時間,使事件線程掛起,直至遠程系統發出答覆爲止。當應用程序調用JProgressBar的setValue方法時,進度條可能更新期內部狀態並調用repaint,這樣做會把一個事件放置到AWT事件隊列中。不幸的是,直至應用程序的事件處理程序完成其處理並把控制權返回到線程的事件處理循環,才能處理該事件。
可以通過調用JComponent的paintImmediately方法來這樣做,該方法有兩種形式:
public void paintImmediately(int x, int y, int width, int height);
public void paintImmediately(Rectangel rect);
例如:
Dimension d = bar.getSize();
Rectangel rect = new Rectangle(0,0, d.width, d.height);
...
bar.setValue(progressValue);
bar.paintImmediately(rect);
...
2)在另一個線程中執行的操作
如果在一個單獨的線程中執行該操作,當調用進度條的setValue方法,它的更新不會出現任何問題,問題在於,後臺線程必須調用JProgressBar 的setValue。而Swing組件只有在事件線程中才能安全的訪問。因此,從執行實際工作的線程調用setValue方法是不安全的!解決的方法是使用SwingUtilites的invokeLater方法,讓AWT事件線程稍後進行setValue調用。
例如:
...
SwingUtilities.invokeLater(new Runnable() {
public void run() {
bar.setValue(value);
}
});
...
還有一種可能,不能再線程中改變swing組件,例如,不能從線程調用label.setText,但是可以使用EventQueue類的invokeLater和invokeAndWait方法,以便在事件調度線程中執行該調用程序。

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/FireElement/archive/2008/05/30/2496699.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章