【发布时间】:2020-10-13 11:56:09
【问题描述】:
(底部代码) 我正在尝试制作的应用程序的一部分涉及一个计时器,我希望能够在应用程序的底角显示这个计时器。我创建了一个线程,将从给定数字(以秒为单位)开始倒计时并在命令行中显示倒计时。
问题是,我不确定如何将此值发送回我的控制器。我试图通过将控制器保存为另一个类中的静态变量来做到这一点,以便可以访问方法和变量等,但这也不起作用,因为我收到了这个错误:
Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:279)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:444)
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$0(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 train.TrainController.updateTime(TrainController.java:34)
at train.Timerr.run(Timerr.java:36)
我想我需要在控制器中添加一个侦听器,但我不知道该怎么做。
在这里,我将做一个简单的例子来说明我想做的事情。一切都在一个新的 javaFX 项目的一个包中。我在这里得到的错误是完全相同的:
主要:
public class Quick extends Application {
@Override
public void start(Stage primaryStage) throws IOException{
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXML.fxml"));
Parent root = loader.load();
Master.savedController = loader.getController();
Scene scene = new Scene(root, 200, 200);
primaryStage.setTitle("KReact");
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
大师班:
public class Master {
public static FXMLController savedController;
}
线程:
public class Timerr extends Thread{
public int t;
Timerr(int time){
t = time;
}
@Override
public void run(){
while(t > 0){
try{
Thread.sleep(1000);
t = t-1;
}catch(InterruptedException e){}
System.out.println(t);
Master.savedController.updateTime(t);
}
}
}
控制器:
public class FXMLController implements Initializable {
@FXML Label time;
public void updateTime(int t){
time.setText(Integer.toString(t));
}
Timerr timer = new Timerr(60);
@FXML public void start(){
timer.start();
}
@Override
public void initialize(URL url, ResourceBundle rb) {
time.setText("60");
}
}
FXML 文件:
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="quick.FXMLController">
<Label fx:id="time" layoutX="80" layoutY="80"/>
<Button onAction="#start"/>
我无法在任何地方找到答案,我认为最好提供一个示例代码以帮助回答我的问题。
非常感谢您提前查看:)
编辑:认为任务中可能有一些我可以做的事情,但仍然找不到。
【问题讨论】:
-
如果你真的想定期更新 UI,根本不要使用后台线程;使用动画。请参阅stackoverflow.com/questions/9966136/…,以及许多其他类似问题。
标签: java multithreading javafx controller