Reputation: 1087
I have a GUI with a TextArea and a Save Button. When I press the latter the text is saved. This takes around 2 seconds. During the process of saving the buttons should get another caption than before and after saving.
Here is my code:
saveButton.setText("Saving...");
Util.print("Saving...");
Thread saveIt = new Thread(new Runnable() {
@Override public void run() {
Platform.runLater(() -> {
try {
Thread.sleep(2000);
} catch (Exception ex) {
Util.print(ex);
}
saveButton.setText("Saved!");
Util.print("Saved!");
});
}
});
saveIt.setDaemon(true);
saveIt.start();
What happens:
The following output is produced on the command line after pressing the button:
Saving...
Saved!
The command line prints "Saving..." directly after I click on saveButton. 2 seconds after pressing saveButton the command line prints "Saved!" and the button caption changes to "Saved!".
What I would expect:
The command line output and the button caption show "Saving..." directly after I click on the save button. After 2 seconds the caption changes to "Saved!".
How can I achieve the expected behaviour?
Thank you very much in advance for your help.
P.S.: I know so many people have had problems with changing GUI elements from Threads. I already read some articles on StackOverflow & the web about it, but this one's a too hard nut for me. Just for reference, here is some of the things I tried so far, among others Tasks:
Constantly Update UI in Java FX worker thread
Why am I getting java.lang.IllegalStateException "Not on FX application thread" on JavaFX?
javafx, update ui from another thread
http://blog.axxg.de/javafx-ui-thread-update/
Upvotes: 1
Views: 2045
Reputation: 342
try wrapping your first setText into a Platform.runLater like this:
Platform.runLater(() -> {
saveButton.setText("Saving...");
});
Every change made to a JavaFX UI component has to been called from the JavaFX thread using the Platform.runLater
Upvotes: 2
Reputation: 1087
I had to put the Thread.sleep() part out of the Platform.runLater() process. Seemingly runLater() must as few workload as possible.
Platform.runLater(() -> {
saveButton.setText("Saving...");
Util.print("Saving...");
});
Thread saveIt = new Thread(new Runnable() {
@Override public void run() {
try {
sleep(2000);
} catch (Exception ex) {
Util.print(ex);
}
Platform.runLater(() -> {
saveButton.setText("Saved!");
Util.print("Saved!");
});
}
});
saveIt.setDaemon(true);
saveIt.start();
Upvotes: 2