JavaFX,标签setText中的倒数计时器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaFX,标签setText中的倒数计时器相关的知识,希望对你有一定的参考价值。
我正在构建用于进行测试的应用程序。我在SceneBuilder中制作了一个场景。 Image下有一个ImageView带有问题和3个按钮“A”,“B”,“C”,文本到按钮和问题的标签是从DataBase中获取的,如果你点击回答新的图像,问题和asnwers正在加载,一切正常,但我想在角落里添加一个Timer。当图像和问题显示在屏幕上时,会有“时间阅读问题”,倒计时从10到0,然后是“回答时间”,然后从10到0再次倒计时。如果计时器结束且没有回答问题,图像会自动改变。但问题是,我可以做计时器,它倒计时,在这之后它改变了问题,但我不知道如何将它放入标签。如果在Timer内部我做了像seconds-- label.setText(秒)之类的事情那么没有错误,但是当我启动应用程序时会有很多异常。你能帮我解决一下这个变量,这个变量在每一秒后递归到计时器吗?
public void setTimer() {
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
if(interval > 0)
{
timeElapsed.setText("Time to read the question: "+interval);
System.out.println(interval);
interval--;
}
else
timer.cancel();
}
}, 1000,1000);
}
现在我有这样的东西,在控制台一切正常,倒计时从10到0但在场景中没有效果。
和错误:
Exception in thread "Timer-0" java.lang.IllegalStateException: Not on FX application thread; currentThread = Timer-0
at javafx.graphics/com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:291)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.graphics/javafx.scene.Parent$3.onProposedChange(Parent.java:493)
at javafx.base/com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
at javafx.base/com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
at javafx.controls/javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:271)
at javafx.controls/javafx.scene.control.skin.LabeledSkinBase.lambda$new$11(LabeledSkinBase.java:219)
at javafx.controls/com.sun.javafx.scene.control.LambdaMultiplePropertyChangeListenerHandler.lambda$new$1(LambdaMultiplePropertyChangeListenerHandler.java:49)
at javafx.base/javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
at javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:181)
at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.base/javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:104)
at javafx.base/javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:111)
at javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:145)
at javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:50)
at javafx.base/javafx.beans.property.StringProperty.setValue(StringProperty.java:65)
at javafx.controls/javafx.scene.control.Labeled.setText(Labeled.java:147)
at gui.controller.StudentTestYesNoController$1.run(StudentTestYesNoController.java:40)
at java.base/java.util.TimerThread.mainLoop(Timer.java:556)
at java.base/java.util.TimerThread.run(Timer.java:506)
答案
问题是您正在尝试从应用程序以外的线程更改UI。
这应该可以解决当前实现的问题
public void setTimer() {
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
if(interval > 0)
{
Platform.runLater(() -> timeElapsed.setText("Time to read the question: "+interval));
System.out.println(interval);
interval--;
}
else
timer.cancel();
}
}, 1000,1000);
}
另外,你可以看一下javafx-Timeline
的具体内容
JavaFX periodic background task
另一答案
再加上mcwolf先生所说的,我认为你需要设置
Platform.setImplicitExit(false);
在Platform.runLater();
之前,每次调用任务时它都会运行。
以上是关于JavaFX,标签setText中的倒数计时器的主要内容,如果未能解决你的问题,请参考以下文章