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