1

I have a JavaFX application that has only one scene that has a Label that is suppose to show the current time in "hh:mm:ss" format and another Label that is suppose to show the current date in either "12/12/12" or "12-12-12". Either would be fine. In the controller I have created two methods that are called on initialization to start a thread for updating the two Labels. The idea is to update the clock every 500ms and the date every one minute or 60000ms. Below shows the code I am using and they are basically the same with the exception of the sleep time and the Label being updated. Here is the error and my code:

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();
}

I have noticed that it seems like the format "hh:mm:ss" seems to be causing the problem because when I exchange it for the date format "MM-dd-yyyy" everything seems to work fine. Any ideas?

1 Answers1

1

You should always use Platform.runLater when updating the UI thread from another thread.

For periodic actions, consider using 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();
Itai
  • 6,641
  • 6
  • 27
  • 51