JavaFX& GUI-Threads:从Thread

时间:2015-06-11 14:11:51

标签: java multithreading user-interface

我有一个带有TextArea和Save按钮的GUI。当我按下后者时,文本被保存。这大约需要2秒钟。在保存按钮的过程中,应该获得比保存之前和之后的另一个标题。

这是我的代码:

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

会发生什么:

按下按钮后,在命令行上生成以下输出:

Saving...
Saved!

命令行打印"保存..."直接点击saveButton后。按下saveButton后2秒,命令行打印"已保存!"并且按钮标题更改为"已保存!"。

我期待的是什么:

命令行输出 和按钮标题 显示"正在保存..."我点击保存按钮后直接点击。 2秒后,标题变为"已保存!"。

如何实现预期的行为?

非常感谢您的帮助。

P.S。:我知道有很多人在从Threads更改GUI元素时遇到了问题。我已经阅读了一些有关StackOverflow& amp;关于它的网络,但这对我来说太难了。仅供参考,以下是我迄今为止尝试过的一些事项,其中包括任务:

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/

2 个答案:

答案 0 :(得分:2)

尝试将第一个 setText包装到Platform.runLater中,如下所示:

Platform.runLater(() -> {
   saveButton.setText("Saving...");
});

必须使用Platform.runLater从JavaFX线程调用对JavaFX UI组件所做的每个更改

答案 1 :(得分:2)

我不得不将Thread.sleep()部分放在Platform.runLater()进程之外。看似runLater()必须尽可能少的工作量。

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