项目场景:
在javafx框架下使用线程更新UI的时候,出现无法正常更新UI。
问题代码如下:
cpp
package clock;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Timer;
import java.util.TimerTask;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class SimpleClock extends Application{
public static void main(String[] args) {
Application.launch();
}
public void start(Stage stage) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
init(stage);
});
}
}, 0, 1000);
}
private void init(Stage stage){
Calendar calendar = new GregorianCalendar();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
ClockPane cPane = new ClockPane(hour, minute, second);
Scene scene = new Scene(cPane, 300, 300);
stage.setTitle("Watch");
stage.setScene(scene);
stage.show();
}
}
问题描述
运行程序之后,出现如下报错:
cpp
Exception in thread "Timer-0" java.lang.IllegalStateException: Not on FX application thread; currentThread = Timer-0
at javafx.graphics@22.0.1/com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:294)
at javafx.graphics@22.0.1/com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:481)
at javafx.graphics@22.0.1/javafx.stage.Stage.setScene(Stage.java:269)
at clock.SimpleClock.init(SimpleClock.java:34)
at clock.SimpleClock$1.run(SimpleClock.java:23)
at java.base/java.util.TimerThread.mainLoop(Timer.java:571)
at java.base/java.util.TimerThread.run(Timer.java:521)
原因分析:
checkFxUserThread
从出错日志看出checkFxUserThread这个方法在检查用户进程是否为UI线程,如果不是会抛出异常,这是因为为了使UI渲染不出现阻塞现象,不允许在子线程中进行UI操作。
解决方案:
可以使用javafx框架提供的runlater方法,实现切换到UI线程来执行更新UI的操作。
cpp
public void start(Stage stage) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Platform.runLater(new Runnable() {
@Override
public void run() {
init(stage);
}
});
}
}, 0, 1000);
}