2013-03-24 75 views
1

我已經做了一個程序,不時地設置一個按鈕的setEnableThread.sleep()是另一類。下面的代碼:Thread.sleep是如何工作的?

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class Try extends JFrame implements ActionListener{ 
JButton n1 = new JButton("1"); 
JButton n2 = new JButton("2"); 
JButton n3 = new JButton("3"); 
JButton show = new JButton("Show"); 

{ 
show.addActionListener(this); 
n1.setEnabled(false); 
n2.setEnabled(false); 
n3.setEnabled(false); 

} 

public Try(){ 
    super("Try"); 
    setVisible(true); 
    setSize(500, 200); 
    setLayout(new GridLayout(1, 4)); 
    add(n1); 
    add(n2); 
    add(n3); 
    add(show); 
} 

public void actionPerformed(ActionEvent a) { 
Object clicked = a.getSource(); 
if(show == clicked){ 
new EasyLevel1().start(); 
} 
} 

    class EasyLevel1 extends Thread { 
    public void run() {  
     try { 
      n1.setEnabled(true); 
      Thread.sleep(1000); 
      n1.setEnabled(false); 
      n2.setEnabled(true); 
      Thread.sleep(1000); 
      n2.setEnabled(false); 
      n3.setEnabled(true); 
      Thread.sleep(1000); 
      n3.setEnabled(false);  
     } catch (InterruptedException e){ 
     } 
     } 
     } 

    public static void main(String[] args){ 
     Try frame = new Try(); 
     frame.setVisible(true); 
    } 
    } 

然而,當我把它放在我的actionListener類中:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class Try extends JFrame implements ActionListener{ 
JButton n1 = new JButton("1"); 
JButton n2 = new JButton("2"); 
JButton n3 = new JButton("3"); 
JButton show = new JButton("Show"); 

{ 
show.addActionListener(this); 
n1.setEnabled(false); 
n2.setEnabled(false); 
n3.setEnabled(false); 

} 

public Try(){ 
    super("Try"); 
    setVisible(true); 
    setSize(500, 200); 
    setLayout(new GridLayout(1, 4)); 
    add(n1); 
    add(n2); 
    add(n3); 
    add(show); 
} 

public void actionPerformed(ActionEvent a) { 
Object clicked = a.getSource(); 
if(show == clicked){ 
      try {n1.setEnabled(true); 
      Thread.sleep(1000); 
      n1.setEnabled(false); 
      n2.setEnabled(true); 
      Thread.sleep(1000); 
      n2.setEnabled(false); 
      n3.setEnabled(true); 
      Thread.sleep(1000); 
      n3.setEnabled(false); 
      } catch (InterruptedException e){} 
} 
} 

public static void main(String[] args){ 
    Try frame = new Try(); 
    frame.setVisible(true); 
} 
} 

它凍結了我的整個程序,從例如基於我明白,一個線程睡眠應在另一個線程中跑來阻止當前課程凍結。但我期望新的thread.sleep仍然凍結它的操作,就像它仍然會執行上面的代碼一樣,但是按鈕會在另一個線程中響應。但令人驚訝的是,它做到了我希望它做的事情,並沒有像第一個程序那樣立即將所有設置設置爲禁用。

回答

2

發生什麼情況是,在第二個示例Thread.sleep正在阻止EDT,因此不會再發生UI更新。相反,在第一個示例中,您正在撥打sleep作爲分隔符Thread,因此不會發生「凍結」。對於這樣的任務,使用Swing Timers是首選。

+0

非常感謝 – 2013-03-24 01:46:17

+0

沒問題,看看'Swing Timers' :) – Reimeus 2013-03-24 01:48:23

+0

是的,雖然我選擇了thread.sleep,因爲它對我更簡單,我目前正在研究你給我的鏈接我瞭解他們。再次感謝 – 2013-03-24 01:53:30

3

Thread.sleep()使當前線程暫停。您正在運行它在actionPerformed,這是在一個Swing事件。所有的Swing操作都是在單線程中完成的,即EDT。當您使用Thread.sleep()暫停它時,Swing無法處理任何其他事件,因爲您尚未從actionPerformed偵聽器返回。因此,GUI凍結(不是完整的應用程序,只是GUI)。

通常,由於這種情況,在Swing事件中執行長時間運行的操作是不好的做法。對於你想要做的,最好的選擇是使用Swing定時器。

+0

謝謝你這是真的信息 – 2013-03-24 01:45:48

2

Thread.sleep將導致執行調用的線程在指定的時間內休眠(或直到線程被中斷)。當您在actionPerformed方法中調用它時,它會導致UI線程進入休眠狀態。這就是你的程序鎖定的原因。

你應該開始一個單獨的線程,它將逐步通過你想在睡眠之間進行的各種調用。或者(更好,在我看來),你可以使用Swing timers做你想做的。

+0

感謝它真的清理了很多在我的腦海裏,所以它真的做我想要的第二個例子,但作爲線程睡它也睡我的gui代碼,所以它「因爲我的gui也正在睡覺「,並在睡眠後變得敏感,因爲它不再睡覺。這是對的? – 2013-03-24 01:45:04

+0

@JerlyTuazon - 確實如此。如果你使用swing定時器來安排各種'setEnabled'調用,你的gui將不會鎖定。 – 2013-03-24 01:56:03

+0

我有一個問題,但它與「凍結」無關,但涉及thread.sleep。爲什麼thread.sleep總是有InterruptedException問題?我的意思是他們已經解釋說,當睡眠受到干擾或什麼的時候。但我已經試過只留下1行來執行線程和它的Thread.sleep,但它仍然說InterruptedException,據我所知我的thread.sleep沒有過早關閉或被打擾? – 2013-03-24 02:13:28