7

アプリケーションのさまざまなステータス メッセージを使用して、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");
}

フローの実行中にこれらのメッセージをラベルに表示して、アプリケーションで行われているさまざまなアクティビティについてユーザーに表示する必要があります。

この動作を実現する方法は?

4

1 に答える 1

26

時間のかかるメソッドを 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);
  }
}
于 2013-11-14T04:51:17.217 に答える