【问题标题】:JavaFX TextArea Update ImmediatelyJavaFX TextArea 立即更新
【发布时间】:2016-08-06 22:09:15
【问题描述】:

我正在使用 Java FX textarea 并使用它来为正在进行的步骤提供信息。

步骤如下。 复制一个文件。 删除旧文件。 复制新文件。 然后将一些属性从旧文件复制到新文件。

这整个步骤从单击按钮开始。

我面临的问题是,一旦我使用附加命令,文本区域并没有被更新。

append 命令添加数据,当函数终止时,我将所有文本放在一起。 我希望在调用函数时更新文本区域。

在我的程序中,复制文件操作需要一些时间,因为它是一个大文件。 因此,在开始时,我会显示操作已开始的消息。 并且在操作结束时我想显示操作已经结束。

但是文本区域会同时显示所有这些文本。

我在 oracle 论坛上看到,FX 中的文本区域使用单个线程,因此在整个过程完成之前不会显示任何内容。

文章:https://community.oracle.com/message/9938117#9938117

谁能建议我该怎么做?

新编辑

点击按钮确定我正在调用一个执行以下方法的函数。

  public void executeCmds(){

        createTempDirectory();
        copyConfigPropetiesFileValues();
        copyConfigProperties();
        copyYMLFile();
        copyYMLFileProperties();

        stopTomcatServer();

        deleteOldWar();
        copyNewWar();
        startTomcatServer();

        copyOldConfigFile();
        copyOldYMLFile();
 }

现在每个函数都是一个进程,应该顺序执行。在每个步骤完成后,我想用成功消息更新 GUI 文本区域。

对于我使用的方法如下:

  public void createTempDirectory(){
         //Creating temporary directory for copying property files
         status_text_area.appendText("Trying to create a temp directory \n");
        File tempDir= new       File(tomcat_path.getText()+filePath.path_to_temp_directory);
         if(!tempDir.exists())
             tempDir.mkdirs();

    status_text_area.appendText("Created Temp directory to copy Config Files \n");

}

其他功能也是如此。 copyWar 文件功能和删除 warfile 功能需要时间,因为它将 130 MB 文件从一个位置复制到另一个位置。

所以我希望 textarea 显示为, 1.开始复制文件 一段时间后

  1. 文件已复制。

但问题是,文本区域根本不会填充,直到所有函数都执行完毕。

如果我尝试通过线程执行这些,则无法保证执行顺序。 请帮忙

【问题讨论】:

标签: java multithreading oracle javafx javafx-2


【解决方案1】:

在后台线程中运行 executeCmds() 方法并使用 Platform.runLater() 更新文本区域:

public void executeCmds(){
    Thread thread = new Thread(() -> {
        createTempDirectory();
        copyConfigPropetiesFileValues();
        copyConfigProperties();
        copyYMLFile();
        copyYMLFileProperties();

        stopTomcatServer();

        deleteOldWar();
        copyNewWar();
        startTomcatServer();

        copyOldConfigFile();
        copyOldYMLFile();
    });
    thread.start();
}

然后

public void createTempDirectory(){
         //Creating temporary directory for copying property files
    updateStatus("Trying to create a temp directory \n");
    File tempDir= new File(tomcat_path.getText()+filePath.path_to_temp_directory);
    if(!tempDir.exists())
        tempDir.mkdirs();

    updateStatus("Created Temp directory to copy Config Files \n");
}

// similarly for other methods

private void updateStatus(String message) {
    if (Platform.isFxApplicationThread()) {
        status_text_area.appendText(message);
    } else {
        Platform.runLater(() -> status_text_area.appendText(message));
    }
}

【讨论】:

  • 天哪!太感谢了。这是完美的,我想要的!我也会在那个 oracle 论坛上发布你的答案。!
【解决方案2】:

扩展已批准的响应 - 如果您需要等待 UI 更新后才能执行其他任何操作,请使用 PlatformImpl.runAndWait(Runnable runnable)

Thread thread = new Thread(() -> {
    yourMethod();
    PlatformImpl.runAndWait(() -> {
        methodForUI();
    });
    methodAfterUIChanged();
});
thread.start();

【讨论】:

    【解决方案3】:

    请您提供一些代码摘录吗?

    我经常犯类似的错误:concat返回连接字符串并且不修改应用了concat方法的字符串。

            String firstString = "txt";
            String resultString = firstString.concat(" next");
    

    如果您的问题确实与线程有关,并且您的代码与您在文章中提到的代码接近,我建议您通过并行线程复制数据,例如 javafx.application.Platform.runLater(e -> { // Do some long operation there }); 请参考已有的关于 Task 和 runlater 的文章: Platform.runLater and Task in JavaFX

    编辑:正如 James_D 提到的,如果操作真的很长,你最好使用任务。阅读我链接的文章,了解有关替代方案及其用法的更多信息。

    【讨论】:

    • Platform.runLater(...) 在 FX 应用程序线程上执行代码。您应该从不在 FX 应用程序线程上执行长时间运行的操作。
    猜你喜欢
    • 2016-09-10
    • 2017-05-24
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多