[英]How can I update the JavaFX application thread from a TimerTask running in a different class?
计时器类
public class LureTimer{
private int totalTime = 0;
private int minutes = 0;
private static Timer mTimer;
private boolean timeRunning;
private static LureUI mLureUI;
private StringProperty theTime = new SimpleStringProperty(this, "theTime", "Test");
public void startTimer(){
System.out.println("Started");
mTimer = new Timer();
mLureUI = new LureUI();
theTimer();
timerStarted();
}
public void theTimer() {
mTimer.schedule(new TimerTask() {
@Override
public void run() {
if (totalTime != 59) {
totalTime++;
timePrint();
} else {
totalTime = 0;
minutes++;
timePrint();
}
checkTime();
}
}, 0, 1000);
}
private void checkTime() {
if(minutes == 30){
stopTimer();
}
}
public void timePrint(){
if (totalTime < 10 && minutes < 10) {
System.out.println("0" + minutes + ":0" + totalTime);
setTheTime("0" + minutes + ":0" + totalTime);
} else if (totalTime >= 10 && minutes < 10){
System.out.println("0" + minutes + ":" + totalTime);
setTheTime("0" + minutes + ":" + totalTime);
}else {
System.out.println(minutes + ":" + totalTime);
setTheTime(minutes + ":" + totalTime);
}
}
public boolean isTimeRunning() {
return timeRunning;
}
public void timerStarted(){
timeRunning = true;
}
public void timerStopped(){
timeRunning = false;
}
public void stopTimer(){
mTimer.cancel();
timerStopped();
resetCounters();
System.out.println("Timer stopped");
}
private void resetCounters() {
totalTime = 0;
minutes = 0;
}
public String getTheTime() {
return theTime.get();
}
public StringProperty theTimeProperty() {
return theTime;
}
public void setTheTime(String theTime) {
this.theTime.set(theTime);
}
}
用户界面
public class LureUI extends Application {
private Button button;
private Button button2;
private LureTimer mLureTimer = new LureTimer();
private Label mLabel;
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Lure Monitor");
button = new Button("Start Timer");
button2 = new Button("Stop Timer");
button.setOnAction(e -> mLureTimer.startTimer());
button2.setOnAction(e -> mLureTimer.stopTimer());
VBox layout1 = new VBox();
layout1.setSpacing(10);
mLabel = new Label();
mLabel.textProperty().bind(mLureTimer.theTimeProperty());
layout1.getChildren().addAll(mLabel, button, button2);
layout1.setAlignment(Pos.CENTER);
Scene scene = new Scene(layout1, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
}
当我运行它时,我得到一个异常...
线程“ Timer-0”中的异常java.lang.IllegalStateException:在FX应用程序线程上不存在; currentThread =计时器-0
我的目标是让mLabel
在UI类从更新theTimer()
它使用方法timePrint()
设置时间。
通过阅读其他文章,我可以看到一个解决方案是Platform.runLater()
,但是它运行了一个新的Runnable对象,但是如何使用TimerTask实现相同的结果?
激光给出的答案
public void theTimer() {
mTimer.schedule(new TimerTask() {
@Override
public void run() {
Platform.runLater(new Runnable() {
@Override
public void run() {
if (totalTime != 59) {
totalTime++;
timePrint();
} else {
totalTime = 0;
minutes++;
timePrint();
}
checkTime();
}
});
}
}, 0, 1000);
}
使用Lambda:
public void theTimer() {
mTimer.schedule(new TimerTask() {
@Override
public void run() {
Platform.runLater(() -> {
if (totalTime != 59) {
totalTime++;
timePrint();
} else {
totalTime = 0;
minutes++;
timePrint();
}
checkTime();
});
}
}, 0, 1000);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.