我有一个JavaFX应用程序只有一个场景,其中一个Label假定以“hh:mm:ss”格式显示当前时间,另一个Label假定以“12 /”显示当前日期12/12“或”12-12-12“。要么没事。在控制器中,我创建了两个在初始化时调用的方法,以启动一个线程来更新两个标签。我们的想法是每隔500毫秒更新一次时钟,每隔一分钟或60000毫秒更新一次。下面显示了我正在使用的代码,除了休眠时间和正在更新的Label之外,它们基本相同。这是错误和我的代码:
WARNING: Uncaught throwable in javafx concurrent thread pool
java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
private void startClockUpdateService() {
Service<Void> clockBackgroundThread = new Service<Void>(){
@Override
protected Task<Void> createTask() {
return new Task<Void>(){
@Override
protected Void call() throws Exception {
while(true){
SimpleDateFormat sdfClock = new SimpleDateFormat("hh:mm:ss");
String date1 = sdfClock.format(new Date());
timeLabel.setText(date1);
Thread.sleep(500);
}
}
};
}
};
clockBackgroundThread.restart();
}
private void startDateUpdateService() {
Service<Void> clockBackgroundThread = new Service<Void>(){
@Override
protected Task<Void> createTask() {
return new Task<Void>(){
@Override
protected Void call() throws Exception {
while(true){
SimpleDateFormat sdfClock = new SimpleDateFormat("MM-dd-yyyy");
String date1 = sdfClock.format(new Date());
dateLabel.setText(date1);
Thread.sleep(60000);
}
}
};
}
};
clockBackgroundThread.restart();
}
我注意到似乎格式“hh:mm:ss”似乎导致问题,因为当我将它换成日期格式“MM-dd-yyyy”时,一切似乎都能正常工作。有什么想法吗?
答案 0 :(得分:1)
从其他线程更新UI线程时,应始终使用Platform.runLater
。
对于定期操作,请考虑使用Timeline
:
KeyFrame update = new KeyFrame(Duration.seconds(0.5), event -> {
// update label here. You don't need to use Platform.runLater(...), because Timeline makes sure it will be called on the UI thread.
});
Timeline tl = new Timeline(update);
tl.setCycleCount(Timeline.INDEFINITE);
tl.play();