2015-10-03 39 views
0

該程序寫入從0到1000的計數,但它只是直接到1000而不顯示計數過程。我使用進度條和Thread.sleep()方法編寫了類似的代碼,並且它完美地工作。在Swing中遇到Thread.sleep的問題

import javax.swing.JFrame; 
import javax.swing.JButton; 
import javax.swing.JTextField; 
import javax.swing.JPanel; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

public class project extends JFrame implements ActionListener { 

    JButton CountUpButton = new JButton("Count up"); 
    JButton CountDownButton = new JButton("Count Down"); 
    JButton ResetButton = new JButton("Reset"); 
    JTextField NumberField = new JTextField(); 
    int count = 0; 

    public project(){ 
     setLayout(new GridLayout(1, 4)); 
     setSize(500, 300); 
     add(NumberField); 
     add(CountUpButton); 
     add(CountDownButton); 
     add(ResetButton); 
     CountUpButton.addActionListener(this); 
     CountDownButton.addActionListener(this); 
     ResetButton.addActionListener(this); 
     NumberField.setText("0"); 
     setVisible(true); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

    } 

    @Override 
    public void actionPerformed(ActionEvent a){ 
     if(CountUpButton.hasFocus()){   
      count = Integer.parseInt(NumberField.getText()); 
      try{ 
      while(count < 1000){ 
       count = count + 1; 
       NumberField.setText(Integer.toString(count)); 
       Thread.sleep(100);     
      } 
      }catch(InterruptedException r){ 
       r.printStackTrace(); 
      } 
     } 
     if(CountDownButton.hasFocus()){ 
      count = Integer.parseInt(NumberField.getText()); 
      try{ 
       while(count > 0){ 
        count -= 1; 
        NumberField.setText(Integer.toBinaryString(count)); 
        Thread.sleep(100);      
       } 
      }catch(InterruptedException r){ 
       r.printStackTrace(); 
      } 
     } 
     if(ResetButton.hasFocus()){ 
      NumberField.setText("0"); 
     } 
    } 

    public static void main(String args[]){ 
     new project(); 
    } 
} 
+0

這是一個瘋狂的猜測,但由於JTextFields通常有一些初始值,然後由用戶修改,並且不希望像這樣以編程方式進行修改,也許您必須明確重新繪製它?只是一個猜測,但很容易嘗試,直到有人提出真正的答案。 :-) – blm

+1

'actionPerformed(...)'在UI線程中被調用,並且你正在調用'Thread.sleep(...)'來阻止它。直到'actionPerformed(...)'返回,用戶界面才能更新。 –

+0

好的,我瘋狂的猜測是錯誤的,對不起。凱文的評論和羅勒的回答對我來說很有意義(我有點懊惱,我沒有想到它,但是自從我做AWT/Swing的東西以來已經有一段時間了。) – blm

回答

3

任何長時間運行的任務都應該在單獨的線程中運行。您對Thread.sleep的使用當然具有長期運行的資格。

通過在Swing用戶界面線程中運行,在代碼完成之前,不會在該用戶界面中呈現任何更新。相反,你的計數應該在另一個線程中產生。該另一個線程應該使用SwingWorker以線程安全的方式定期更新用戶界面。

研究launching threadsexecutors,如ScheduledExecutorService,Swing event-dispatch thread(EDT)和SwingWorker。

搖擺定時器

更簡單的方法可能是Swing Timer classTutorial),不要與java.util.Timer混淆。它會爲你做很多線程處理工作。但我沒有經驗。

+1

使用Swing Timer對於「動畫櫃檯」更爲常見(也更簡單)。 –

+0

@AndrewThompson爲Swing Timer添加了提及和鏈接。謝謝。 –

+0

*「它聲稱爲你執行大部分的線程處理工作」*在它所基於的'ActionListener'的'actionPerformed'中調用的代碼語句*可以保證*在EDT上被調用。這不是一個真正負擔CPU負擔的地方(例如對圖像進行復雜渲染)或網絡或文件密集型操作,但對於主要處理GUI元素的「短期」重複任務。 –