In your code you block the JavaFX application thread that is responsible for redrawing the UI. This way any changes in the GUI won't be visible and events won't be handled, ect.
You could use a Task
and add a listener to the message
property for diplaying the messages. Updates for this property are guarantied to be executed on the application thread. The only drawback is that for fast updates to the property some notifications could be skipped.
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
// update message property
updateMessage("Hello World 1!");
Thread.sleep(500);
updateMessage("Hello World 2!");
Thread.sleep(500);
updateMessage("Hello World 3!");
Thread.sleep(500);
return null;
}
};
// display message changes as notifications
task.messageProperty().addListener((observable, oldMessage, newMessage) ->
Notifications.create().title("Title Text").text(newMessage).darkStyle().show());
// execute long running task on background thread
new Thread(task).start();
If you need every message to be displayed, you should use Platform.runLater
to trigger the notifications.
Thread thread = new Thread(new Runnable() {
private void postMessage(final String message) {
Platform.runLater(() -> Notifications.create().title("Title Text").text(message).darkStyle().show());
}
@Override
public void run() {
try {
postMessage("Hello World 1!");
Thread.sleep(500);
postMessage("Hello World 2!");
Thread.sleep(500);
postMessage("Hello World 3!");
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(NotificationsTestMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
thread.start();
Note that you should take care not to use Platform.runLater
too often. In case there are many updates, it's sometimes best to group them. However in this case you'll probably not want to use notifications anyway, since there would simply be to many to display all of them. Nontheless here's some code that demonstrates grouping the updates:
private final List<String> messageQueue = new ArrayList<>();
private boolean updating;
private final Runnable updater = () -> {
synchronized (messageQueue) {
for (String message : messageQueue) {
Notifications.create().title("Title Text").text(message).darkStyle().show();
}
messageQueue.clear();
updating = false;
}
};
private void postMessage(String message) {
synchronized (messageQueue) {
messageQueue.add(message);
if (!updating) {
updating = true;
Platform.runLater(updater);
}
}
}