2010-04-07 72 views
1

我試圖讓JProgressBar遞增1每1/100秒,而且目前我使用Thread.sleep(100) while語句裏面,像這樣:進度條遞增1每隔100個第二

try { 
     while (i<=100){ 
      doTime(); 

     } 
    } catch (InterruptedException ex) { 
     Logger.getLogger(SplashScreen.class.getName()).log(Level.SEVERE, null, ex); 
    } 

public void doTime() throws InterruptedException{ 


     jLabel1.setText("sleeping"); 
     Thread.sleep(100); 
     jLabel1.setText("start"); 
     i++; 
     pb.setValue(i); 
     pb.repaint(); 

} 

如果我通過執行調試System.out.println它實時顯示,但擺動GUI凍結,直到它退出while循環任何人都可以幫助?

感謝

亞光

回答

5

如派生所說,你應該使用SwingWorker。從它的javadoc:

「SwingWorker適用於需要在後臺線程中運行長時間運行的任務,並在完成時或處理時向用戶界面提供更新的場合。 SwingWorker的子類必須實現doInBackground()方法來執行後臺計算。「

在java教程中對ProgressBarDemo.java做了這樣的細微修改,你幾乎可以得到你想要的。

public Void doInBackground() { 
     Random random = new Random(); 
     int progress = 0; 
     //Initialize progress property. 
     setProgress(0); 
     while (progress < 100) { 
      //Sleep for up to one second. 
      try { 
       //original code: Thread.sleep(random.nextInt(1000)); 
       Thread.sleep(10); 
      } catch (InterruptedException ignore) {} 
      //Make random progress. 
      //originalcode: progress += random.nextInt(10); 
      progress++; 
      setProgress(Math.min(progress, 100)); 
     } 
     return null; 
    } 
2

的問題是,你在睡覺的Swing事件線程。您需要創建一個用於運行循環的新線程,然後讓該循環更新swing事件線程上的進度條。

我會使用Swing Worker thread作爲循環。然後使用invokeLater來更新進度條。

另一個好的swing/thread tutorial

1

除了派生說,你睡100毫秒。這意味着你只更新每十分之一秒,而不是每百分之一。

1

如果doTime()被稱爲事件指派線程(EDT),它應該,因爲它被調用UI代碼(jLabel1.setText()等)內,那麼它應該被調用sleep()可言。你不想凍結你的用戶界面。

這樣做的正確方法是使用timer在正確時刻(比如說,每10毫秒)喚醒並更新進度。由Jala代碼也是一個很好的答案,它是官方的Swing Way服務(定時器比SwingWorkers低一級)。

+0

+1下面是javax.swing.Timer每隔100 ms更新一次'JLabel'的簡單示例。 http://stackoverflow.com/questions/2576353/stop-a-stopwatch/2576909#2576909 – trashgod 2010-04-07 16:37:01