Java:计时器(等待x秒)

Java:计时器(等待x秒),java,timer,Java,Timer,我有一个简单的GUI,可以保存.doc文件中的数据并从中获取数据 当我按下保存按钮时,我有一个标签,通过label.setText()显示“成功”或“错误” 更新:代码将在FXMLDocumentController(内置的påSceneBuilder)中运行 我希望标签在3秒钟后恢复为空(“”) 我试过: try { Thread.sleep(1000); } catch(InterruptedException ex) { Thread.cu

我有一个简单的GUI,可以保存.doc文件中的数据并从中获取数据

当我按下保存按钮时,我有一个标签,通过label.setText()显示“成功”或“错误”

更新:代码将在FXMLDocumentController(内置的påSceneBuilder)中运行

我希望标签在3秒钟后恢复为空(“”)

我试过:

try {
    Thread.sleep(1000);               
    } 
 catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}


但是,睡眠功能冻结了整个GUI,所以我不能在它睡眠时与它交互。如何设置不影响可用性的计时器?:)

您无法与GUI交互,因为代码正在负责处理GUI事件的事件分派线程中休眠,因此被阻止。用这个秋千代替

这里给出的例子很简单。我将评论包括在内

  int delay = 1000; //milliseconds

  //Create action listener which listens for the event generated by the timer
  ActionListener taskPerformer = new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
          Place here code to execute when the time runs out.
      }
  };
  //Simply create a timer with the created listener and start it.
  new Timer(delay, taskPerformer).start();

不要使用
Thread.sleep()
。实例化一个
javax.swing.Timer
,并让它执行事件回调。如果要将其保持在相同的方法中,请调用
wait()
,然后让事件处理程序调用
notify()
,这将恢复程序。但是,您可能不需要这样做;您可以直接使用事件处理程序删除文本。

要执行此操作,您必须使用。如果您正在使用Swing,则可以使用Swing计时器。代码看起来像这样。将此代码放在“保存”文件的位置

  int delay = 3000; 
  ActionListener taskPerformer = new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
          //Empty the label here. This code will be called once the timeout of three seconds has been passed
      }
  };
  new Timer(delay, taskPerformer).start();
您可以启动另一个线程来处理此问题。只需在另一个线程中进行处理。睡眠3秒钟,然后清除lbl

下面是一个示例,展示了它的工作原理:

class runnable implements Runnable {
    Test test;
    public runnable(Test test)
    {
        this.test = test;
    }
    public void run() {
        try {
            Thread.sleep(3000);
            this.test.test = "test2";
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Hello from a thread!");
    }

}

public class Test {
    public String test = "test";
    public static void main(String[] args) throws InterruptedException{
        Test test = new Test();
        System.out.println(test.test);
        (new Thread(new runnable(test))).start();
        Thread.sleep(4000);
        System.out.println(test.test);
    }
}
************************************************************更新*************************************************************

class runnable implements Runnable {
    Test test;
    public runnable(Test test)
    {
        this.test = test;
    }
    public void run() {
        try {
            Thread.sleep(3000);
            this.test.label.setText("This is a test.");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Hello from a thread!");
    }

}

public class Test {
    public String test = "test";
    JLabel label = new JLabel("Test");
    JFrame frame = new JFrame();
    JButton button = new JButton();
    public static void main(String[] args) throws InterruptedException{
        Test test = new Test();
        test.label.setText("Test");
        test.button.setText("Test Button");
        test.button.setSize(50, 50);
        test.frame.setSize(500, 500);
        test.frame.add(test.button);
        test.frame.add(test.label);
        test.frame.setVisible(true);
        test.button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                System.exit(0);
            }

        });
        (new Thread(new runnable(test))).start();
    }
}

您的问题是您正在阻止UI线程。它无法更新任何内容,主循环中断。你可以像其他人回答的那样使用
计时器
对象来完成你的目标,或者如果你不想,你可以实现自己的线程来完成同样的任务。

创建一个计时器任务,该任务在3秒后启动。 此TimerTask必须通过Platform.runLater(new Runnable())执行使用gui组件的代码


我对java不是很有经验(还没有:D),所以您能给我一个代码示例,让我等待3秒钟,然后执行label.setText(“”?我没有因此得到编译错误,但是下面的运行时错误:线程“Timer-0”java.lang.IllegalStateException中的异常:不在FX应用程序线程上;currentThread=Timer-0Oh。如果您使用的是javafx,则必须使用Platform.runLater()处理此问题,以便在gui线程中运行代码。我更新了我的帖子谢谢你的时间:)我现在收到这个编译错误:错误:找不到symbol Platform.runLater(new Runnable()){symbol:variable Platform您是否使用了正确的平台类?javafx.application.PlatformYes:import javafx.application.Platform;如果OP在Swing中需要一个计时器,那么这并不是最好的方法,因为Swing提供了自己的计时器。更不用说来自其他thead的代码将不会在调度线程上运行。1.如果有太多si,为什么要使用线程mpler实现方法?2.第二个线程中的代码不得更新Swing,除非您在EDT(另一个可运行)上调用它,因此上面的示例是错误的,除非您添加它。我试图使用您的代码,但我正在从我的FXML DocumentController.java(它控制我的GUI标签的所有输入/输出)调用该方法-我如何从runnable类中访问label.setText():/@CasperTL我更新了我的帖子,查看了构造函数和如何传入对象。只需使用你的label对象,而不是像我刚才使用的一般对象,我只是举了一个例子…@brso05谢谢!我会尝试一下,给我一分钟:)
class runnable implements Runnable {
    Test test;
    public runnable(Test test)
    {
        this.test = test;
    }
    public void run() {
        try {
            Thread.sleep(3000);
            this.test.label.setText("This is a test.");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Hello from a thread!");
    }

}

public class Test {
    public String test = "test";
    JLabel label = new JLabel("Test");
    JFrame frame = new JFrame();
    JButton button = new JButton();
    public static void main(String[] args) throws InterruptedException{
        Test test = new Test();
        test.label.setText("Test");
        test.button.setText("Test Button");
        test.button.setSize(50, 50);
        test.frame.setSize(500, 500);
        test.frame.add(test.button);
        test.frame.add(test.label);
        test.frame.setVisible(true);
        test.button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                System.exit(0);
            }

        });
        (new Thread(new runnable(test))).start();
    }
}
Timer timer = new Timer();
timer.schedule(new TimerTask() {

        @Override
        public void run() {
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    label.setText("");
                }
            });

        }
    }, 3000);