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

JavaFx:在应用程序执行不同方法时,使用消息异步更新UI标签,java,jakarta-ee,asynchronous,javafx-2,Java,Jakarta Ee,Asynchronous,Javafx 2,我正在尝试使用应用程序的各种状态消息异步更新JavaFXGUI中的标签 例如 我的应用程序中的按钮“update”调用控制器中的方法updateSettings()。现在,我尝试用以下方式更新UI上的标签 @FXML private void updateSettings() { label.text("message1"); //some action lable.text("action done"); label.text("calling metho

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

例如

我的应用程序中的按钮“update”调用控制器中的方法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应用程序线程之外运行耗时的方法(在一个线程中)。任务中有特殊的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.concurrent.Task;
导入javafx.scene.scene;
导入javafx.scene.control.*;
导入javafx.stage.*;
导入javafx.application.*;
公共类MessagingDemo扩展了应用程序{
公众假期开始(阶段){
//“message1”不会被看到,因为我们将在JavaFX上执行下一个操作
//然后,应用程序线程再次更新标签文本,而不释放
//线程到JavaFX系统。
标签=新标签(“消息1”);
标签宽度(300);
//一些行动
//“action done”不会被看到,因为我们在下一个语句中再次设置了文本。
label.setText(“完成的操作”);
//您不会看到这一点,因为我们会立即将文本绑定到任务文本并启动任务。
text(“调用方法..等待一段时间”)
任务=新任务(){
@Override public Void call()引发InterruptedException{
//“message2”耗时的方法(将看到此消息)。
更新消息(“消息2”);
//一些行动
睡眠(3000);
//“message3”耗时的方法(将看到此消息)。
更新消息(“消息3”);
//更耗时的操作
睡眠(7000);
//这将永远不会被实际看到,因为我们还设置了一个消息
//在task::setOnSucceeded处理程序中。
updateMessage(“耗时的方法成功完成”);
返回null;
}
};
label.textProperty().bind(task.messageProperty());
//java 8构造,如果使用java 7,则替换为java 7代码。
task.setonsucceed(e->{
label.textProperty().unbind();
//将看到此消息。
label.setText(“操作成功完成”);
});
线程线程=新线程(任务);
setDaemon(true);
thread.start();
舞台场景(新场景(标签));
stage.show();
}
公共静态void main(字符串参数[]){
发射(args);
}
}

这工作非常好。但是,如何能够捕获或分派任务中发生的异常到任务开始的上下文中呢?请以新问题的形式提出新问题。听音乐