2013-03-24 37 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