Java 为什么线睡不好?
我试图创建一个简单的JButton,当被单击时,它会导致一个简单的JLabel将其文本更改为“第二个文本”,然后我希望当前线程睡眠几秒钟,最后JLabel再次更改其文本,这次更改为“第三个文本”。我想我已经在这里完成了,但是它没有按照我想要的方式工作。下面提供的代码使JButton在指定的时间段内冻结,就好像它被按下一样,然后标签变为第三种状态。换句话说,“秒文本”不会出现 请告诉我该怎么做 多谢各位Java 为什么线睡不好?,java,multithreading,Java,Multithreading,我试图创建一个简单的JButton,当被单击时,它会导致一个简单的JLabel将其文本更改为“第二个文本”,然后我希望当前线程睡眠几秒钟,最后JLabel再次更改其文本,这次更改为“第三个文本”。我想我已经在这里完成了,但是它没有按照我想要的方式工作。下面提供的代码使JButton在指定的时间段内冻结,就好像它被按下一样,然后标签变为第三种状态。换句话说,“秒文本”不会出现 请告诉我该怎么做 多谢各位 package testPackage; import java.awt.event.Act
package testPackage;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Demo {
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame();
JButton button = new JButton("Click me!");
final JLabel label = new JLabel("first text");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
JPanel panel = new JPanel();
panel.add(button);
panel.add(label);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
label.setText("second text");
try {
Thread.currentThread();
Thread.sleep(4000);
} catch (InterruptedException exc) {
System.out.println("Erorrrrr");
}
}
});
frame.add(panel);
frame.setVisible(true);
}
}
GUI在线程上运行。当您将该线程休眠x秒时,GUI将冻结x秒
正如马尔科评论中所说的,“你必须用Javax、Swing、Time[/P>>P>]来安排一个延迟事件。当你考虑java内部时,文本属性的改变并不是唯一需要做的事情来查看结果。控件也必须重新绘制(可能无效)
通过调用sleep,实际上可以阻止javagui内部工作者重新绘制更改的控件。它只能在睡眠完成后发生。如果在事件调度线程(处理GUI事件的线程)上睡眠,则GUI将冻结。您可以从action listener启动一个后台线程,并将其发送到休眠线程 public void actionPerformed(ActionEvent e) { label.setText("text 1"); new Thread(new Runnable() { public void run() { try { Thread.sleep(1000); }catch (InterruptedException ignore){} // queue Swing code for execution on the EDT EventQueue.invokeLater(new Runnable() { public void run() { label.setText("text2"); } }); } }).start(); } 已执行的公共无效操作(操作事件e) { label.setText(“文本1”); 新线程(newrunnable()) { 公开募捐 { 试一试{ 睡眠(1000); }捕获(中断异常忽略){} //用于在EDT上执行的队列摆动代码 invokeLater(新的Runnable() { 公开募捐 { label.setText(“text2”); } }); } }).start();
} 在ActionPerformed方法中,您需要释放主GUI线程,以便发生更改: 因此,如果在actionPerformed方法中打开一个新线程,它将释放主GUI线程,然后在睡眠后调用label.setText(“第三个文本”),这将把标签更改为第二个文本,首先等待4秒,然后再将其更改为第三个文本
@Override
public void actionPerformed(ActionEvent e) {
label.setText("second text");
new Thread(){
public void run(){
try {
//Thread.currentThread();
Thread.sleep(4000);
label.setText("third text");
} catch (InterruptedException exc) {
System.out.println("Erorrrrr");
}
}
}.start();
}
这是这里最常见的问题之一。您正在使事件调度线程休眠,冻结GUI。您必须改为使用
javax.swing.Timer
计划一个延迟事件。另外,您希望语句Thread.currentThread()代码>要实现?第三个文本在哪里?可能的副本需要使用invokeLater运行label.setText(“第三个文本”),或者在EDT外部修改gui。Thread.currentThread()代码>什么也不做。你为什么这么说?是的,这里没有用,这是问题中的复制粘贴错误。我会评论出来的,谢谢你指出,伙计。