简体   繁体   中英

JavaFX & GUI-Threads: Change button text from Thread

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.

PS: 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/

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM