Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么线睡不好?_Java_Multithreading - Fatal编程技术网

Java 为什么线睡不好?

Java 为什么线睡不好?,java,multithreading,Java,Multithreading,我试图创建一个简单的JButton,当被单击时,它会导致一个简单的JLabel将其文本更改为“第二个文本”,然后我希望当前线程睡眠几秒钟,最后JLabel再次更改其文本,这次更改为“第三个文本”。我想我已经在这里完成了,但是它没有按照我想要的方式工作。下面提供的代码使JButton在指定的时间段内冻结,就好像它被按下一样,然后标签变为第三种状态。换句话说,“秒文本”不会出现 请告诉我该怎么做 多谢各位 package testPackage; import java.awt.event.Act

我试图创建一个简单的JButton,当被单击时,它会导致一个简单的JLabel将其文本更改为“第二个文本”,然后我希望当前线程睡眠几秒钟,最后JLabel再次更改其文本,这次更改为“第三个文本”。我想我已经在这里完成了,但是它没有按照我想要的方式工作。下面提供的代码使JButton在指定的时间段内冻结,就好像它被按下一样,然后标签变为第三种状态。换句话说,“秒文本”不会出现

请告诉我该怎么做

多谢各位

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()什么也不做。你为什么这么说?是的,这里没有用,这是问题中的复制粘贴错误。我会评论出来的,谢谢你指出,伙计。