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

DHR*_*SAL 7 java asynchronous java-ee javafx-2

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

例如

我的Application中的按钮"更新"调用控制器中的方法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");
}
Run Code Online (Sandbox Code Playgroud)

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

如何实现这种行为?

jew*_*sea 26

您从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);
  }
}
Run Code Online (Sandbox Code Playgroud)