Exception in thread "Thread-5" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-5
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:279)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
at com.sun.javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:575)
at com.sun.javafx.scene.control.skin.LabeledSkinBase.handleControlPropertyChanged(LabeledSkinBase.java:204)
at com.sun.javafx.scene.control.skin.LabelSkin.handleControlPropertyChanged(LabelSkin.java:49)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$70(BehaviorSkinBase.java:197)
at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:103)
at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:144)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
at javafx.beans.property.StringProperty.setValue(StringProperty.java:65)
at javafx.scene.control.Labeled.setText(Labeled.java:145)
at edu.controller.GUIController.statusShow(GUIController.java:443)
at edu.controller.GUIController.lambda$7(GUIController.java:214)
at java.lang.Thread.run(Unknown Source)我正在制作一个文本编辑器,我想在页脚中添加一个状态栏,在几秒钟后告诉用户不同的提示,当我试图在标签上设置文本时,但是当我试图在控制台上设置文本时,我会遇到这个错误。
new Thread(()->{
statusBarShow();
}).start();
private void statusBarShow(){
try {
statusLable.setText("Tip 1");
Thread.sleep(2000);
statusLable.setText("Tip 2");
Thread.sleep(2000);
statusLable.setText("Tip 3");
Thread.sleep(2000);
statusLable.setText("Tip 4");
Thread.sleep(2000);
statusLable.setText("Tip 5");
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}发布于 2019-07-16 20:06:31
唯一允许修改JavaFX图形用户界面的线程是JavaFX线程。如果任何其他线程修改UI,您将得到一个异常。
对于这个常见问题,最简单的答案是包装在Platform.runLater()中更改图形用户界面的代码。请注意,不要将任何睡眠放置在run后()中,因为它们将导致JavaFX GUI线程休眠,这将导致程序在睡眠期间冻结。
Platform.runLater()具有以下javadoc:
在未来某个未指定的时间在JavaFX应用程序线程上运行指定的可运行程序。该方法可以从任何线程调用,它将把Runnable发送到事件队列,然后立即返回给调用者。运行程序按照发布的顺序执行。传入runLater方法的runnable将在任何Runnable传递到随后对runLater的调用之前执行。如果在JavaFX运行时被关闭后调用此方法,则将忽略该调用: Runnable将不会被执行,也不会引发任何异常。 注意:应用程序应该避免过多的挂起的可运行程序淹没JavaFX。否则,应用程序可能会变得没有响应。鼓励应用程序将多个操作分批到更少的runLater调用中。此外,在可能的情况下,应该在后台线程上执行长时间运行的操作,为GUI操作释放JavaFX应用程序线程。 在FX运行时初始化之前,不能调用此方法。对于扩展应用程序的标准JavaFX应用程序,并使用JavaFX或应用程序类中的一个启动方法来启动应用程序,FX运行时是在加载应用程序类之前由启动程序初始化的。对于使用JFXPanel显示FX内容的Swing应用程序,在构造第一个JFXPanel实例时将初始化FX运行时。对于使用FXCanvas显示FX内容的SWT应用程序,在构造第一个FXCanvas实例时将初始化FX运行时。
我不认为您的代码是以最好的方式来完成此任务的,但是一个非常简单的解决方案是:
new Thread(()->{
statusBarShow();
}).start();
private void statusBarShow(){
try {
Platform.runLater(()->statusLable.setText("Tip 1"));
Thread.sleep(2000);
Platform.runLater(statusLable.setText("Tip 2"));
Thread.sleep(2000);
Platform.runLater(statusLable.setText("Tip 3"));
Thread.sleep(2000);
Platform.runLater(statusLable.setText("Tip 4"));
Thread.sleep(2000);
Platform.runLater(statusLable.setText("Tip 5"));
} catch (Exception e) {
e.printStackTrace();
}
}解决问题的一个更好的方法可能是使用AnimationTimer。
下面是关于如何实现这一目标的有用线索:JavaFX周期背景任务
https://stackoverflow.com/questions/57064614
复制相似问题