当前位置: 首页 > 面试题库 >

JavaFx:在执行应用程序不同方法时,与消息异步更新UI标签

祝俊
2023-03-14
问题内容

我正在尝试使用各种状态消息为应用程序异步更新JavaFx GUI中的标签。

例如

我的应用程序中的“更新”按钮在控制器中调用方法updateSettings()。现在,我尝试以以下方式更新UI上的标签。

@FXML
private void updateSettings() {
    label.text("message1");

    //some action

    lable.text("action done");

    label.text("calling method.. wait for some time")
    // call to time consuming method - timeConsumingMethod();

    label.text
    label.text("operation completely successfully");
}

private void timeConsumingMethod() {

    label.text("message2");
    //some actions
    label.text("message3");

    //more  time consuming actions
    label.text("time consuming method is done with success");
}

我希望这些消息应在流程执行时显示在标签中,以向用户显示应用程序中正在进行的各种活动。

如何实现这种行为?


问题答案:

您可以在JavaFX应用程序线程之外(在Task中)运行耗时的方法。任务中具有特殊的API,可轻松提供状态消息,这些消息可以在绑定的标签中显示。

我对以下代码所做的工作是尝试创建一个模拟您在问题中提供的建议流程和消息报告的系统。由于代码中记录的各种原因,用户只能看到一些消息。

import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.stage.*;
import javafx.application.*;

public class MessagingDemo extends Application {
  public void start(Stage stage) {
    // "message1" won’t be seen because we perform the next action on the JavaFX 
    // application thread then update the label text again without releasing the 
    // thread to the JavaFX system.
    Label label = new Label("message1");
    label.setPrefWidth(300);

    // some action

    // "action done" won’t be seen because we set text again in the next statement.
    label.setText("action done");

    // you're not going to see this because we immediately bind text to the task text and launch the task. 
    label.text("calling method.. wait for some time")

    Task <Void> task = new Task<Void>() {
      @Override public Void call() throws InterruptedException {
        // "message2" time consuming method (this message will be seen).
        updateMessage("message2");

        // some actions
        Thread.sleep(3000);

        // "message3" time consuming method (this message will be seen).
        updateMessage("message3");

        //more  time consuming actions
        Thread.sleep(7000);

        // this will never be actually be seen because we also set a message 
        // in the task::setOnSucceeded handler.
        updateMessage("time consuming method is done with success");

        return null;
      }
    };

    label.textProperty().bind(task.messageProperty());

    // java 8 construct, replace with java 7 code if using java 7.
    task.setOnSucceeded(e -> {
      label.textProperty().unbind();
      // this message will be seen.
      label.setText("operation completed successfully");
    });

    Thread thread = new Thread(task);
    thread.setDaemon(true);
    thread.start();

    stage.setScene(new Scene(label));
    stage.show();
  }

  public static void main(String args[]) {
    launch(args);
  }
}


 类似资料:
  • 在过去的几天里,我一直在尝试JavaFX、FXML、任务和属性。我偶然发现了一种奇怪的行为,希望您能帮助我更好地理解正在发生的事情。 我有一个极简的GUI,看起来像这样:GUI 如果我单击按钮,就会创建并启动一个新任务。此任务会增加一个双属性,并且新值会写入标签并在ProgressBar中设置。任务代码可以在这里看到: FXML控制器的代码如下: 如果我运行此代码,尝试更新标签会导致以下异常:ja

  • 问题内容: 当我尝试在Eclipse中运行更新管理器时,出现错误“无法启动更新UI。尚未为软件更新正确配置此安装”。 有谁知道如何解决这一问题? 问题答案: 关于该消息,已经输入了一些错误: 错误238910:如果您的日食错误日志包含: !MESSAGE解析配置文件/opt/eclipse/p2/org.eclipse.equinox.p2.engine/profileRegistry/SDKPr

  • 我已经得到推送通知工作,并设法更新图标徽章计数时,应用程序被带到前台。 但我对此有点困惑。。。iPhone收到通知,弹出消息显示激活我的应用程序,徽章仅在我启动应用程序后更新。 就用户体验而言,这听起来并不正确。我的理解是,徽章计数应该通过递增计数通知用户需要采取的行动,但这要等到应用程序运行的后期才会发生。 那么,当应用程序在后台收到推送通知时,有没有办法告诉它更新徽章计数? 请注意,我的应用程

  • 问题内容: 在过去的几个小时中,我一直在努力解决这个问题,但无法解决。我想我仍然必须习惯于函数式编程风格;) 我写了一个递归函数,它遍历目录结构并对某些文件进行处理。此功能使用异步IO方法。现在,我要在完成整个遍历后执行一些操作。 如何确保在执行完所有调用但仍使用异步IO功能后执行此操作? 问题答案: 查找“ 步骤”模块。它可以链接异步函数调用,并将结果从一个传递到另一个。

  • 问题内容: 我在执行后台任务时使JavaFX UI保持活动状态时遇到问题。我已经设置了这个非常简单的代码- 我希望发生的事情是让进度条每1秒钟更新一次,直到任务完成。而是,UI完全冻结10秒钟,之后进度条显示为完成。明确地说- 问题不仅在于所有更新最终一次出现,而且UI直到那时都完全没有响应。 我已经阅读了有关此主题的其他任何问题,但找不到答案。我究竟做错了什么? 谢谢。 问题答案: 使用 sta

  • 我正在将SpringWebSocket 4.2.4与sockjs和stomp一起使用,并试图在异步任务中从服务器向所有订阅者发送消息,但运气不佳 我的班级是: 但是订阅者没有得到消息 有什么帮助吗?我做错了什么:( *编辑* 我的消息代理: 当我订阅时: 谢谢 **编辑2:** 谢谢你帮我解决这个问题:)