1

我制作了一个setEnable不时设置按钮的程序。在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 仍会冻结其操作,就像它仍会执行上面的代码一样,但按钮将响应,因为它位于另一个线程中。但令人惊讶的是,它完成了我想要它做的事情,它并没有像第一个程序那样立即将所有内容设置为禁用。

4

3 回答 3

3

Thread.sleep()使当前线程暂停。您正在运行它actionPerformed,即在 Swing 事件中。所有 Swing 操作都在单个线程(EDT)中完成。当您使用 Thread.sleep() 暂停它时,Swing 无法处理任何其他事件,因为您还没有从 actionPerformed 侦听器返回。因此,GUI 冻结(不是完整的应用程序,只是 GUI)。

通常,因此在 Swing 事件中执行长时间运行的操作是不好的做法。对于您正在尝试做的事情,一个不错的选择是使用 Swing 计时器。

于 2013-03-24T01:25:07.007 回答
2

Thread.sleep将导致执行调用的线程休眠指定的时间(或直到线程被中断)。当您在actionPerformed方法中调用它时,它会导致 UI 线程休眠。这就是你的程序被锁定的原因。

您应该启动一个单独的线程,该线程将逐步完成您想要在两者之间进行的各种调用。或者(在我看来更好)你可以使用Swing 计时器来做你想做的事。

于 2013-03-24T01:25:48.130 回答
2

正在发生的事情是,在第二个示例Thread.sleep中阻止了EDT进一步的 UI 更新。相反,在第一个示例中,您调用sleep的是单独的Thread,因此不会发生“冻结”。对于这样的任务,最好使用Swing Timers

于 2013-03-24T01:26:07.707 回答