2017-08-16 15 views
0

私はメソッドを持つクラスがある場合:JavaFX並行性:タスク内でオブジェクトメソッドを実行できますか?

class Car{ 
    private String engineRPM; 

    public Car(){} 

    public String idleEngine(){ 
     if (engineOn()){ 
      engineRPM = getEngineRPM(); 
     } 
     return engineRPM; 
    } 
} 

がどのように私はメインのバックグラウンドスレッドでタスクのメソッドを実行しないと、その戻り値を取り、GUIを更新しますか?

public class Main extends Application { 

Car myCar; 

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

} 

@Override 
public void start(Stage primaryStage) throws Exception{ 
    FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/entry.fxml")); 
    Parent root = loader.load(); 
    this.mainController = (SystemMessage) loader.getController(); 
    primaryStage.setTitle("Car"); 
    primaryStage.setScene(new Scene(root, 300, 275)); 
    primaryStage.show(); 

    //perform background task of class method here 
    myCar = new Car(); 
    myCar.startEngine(); 
    String RPM = myCar.engineIdle(); // 
    this.mainController.postMessage(RPM); 

} 
+0

あなたはそれを行うにはPlatform.runLater(Runnableを...)を使用することができます。これをチェックしてください:https://stackoverflow.com/questions/13784333/platform-runlater-and-task-in-javafx – Serge

+1

@Serge 'Platform.runLater(...)は'ない上、FXのアプリケーションスレッドで何かを実行しますバックグラウンドスレッド。ですから、UIの最後にはPlatform.runLater(...)を使用してください。コメントからは分かりません。 –

+0

@James_Dはい、これは私が言ったことです。ご注意ください。 – Serge

答えて

1

基本的な考え方は、

  • call()方法あなたはFXのアプリケーションスレッド上で実行するために何かを持っている場合は、バックグラウンドスレッド
  • で行う必要があるものは何でもないTaskを作成していますタスクが終了すると、call()方法は
  • ときを完了した後(FXのアプリケーションスレッドで)呼び出されonSucceededハンドラを使用しますあなたは
  • がタスクからスレッドを作成して返されたかを確認するgetValue()を呼び出し、そう

でそれを実行するためにstart()を呼び出すことができますので、それから返されるどんなメソッドが終了すると、タスクのvalueとして設定されていますあなたのケースでは、これはちょうど見えます

public class Main extends Application { 


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

    } 

    @Override 
    public void start(Stage primaryStage) throws Exception{ 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/entry.fxml")); 
     Parent root = loader.load(); 
     SystemMessage mainController = loader.getController(); 
     primaryStage.setTitle("Car"); 
     primaryStage.setScene(new Scene(root, 300, 275)); 
     primaryStage.show(); 

     Task<String> carTask = new Task<String>() { 
      @Override 
      protected String call() throws Exception { 
       Car myCar = new Car(); 
       myCar.startEngine(); 
       return myCar.engineIdle(); 
      } 
     }; 
     carTask.setOnSucceeded(e -> mainController.postMessage(carTask.getValue())); 
     new Thread(carTask).start(); 

    } 

} 

ように documentation for Taskを参照してください:それはたくさんの例があります。

+0

これはクリックし始めている!!!ありがとうございました。もう1つの質問。タスクの中でいくつかのメソッドを実行したいのであれば、それぞれの 'postMessage'メソッドを使ってGUIを更新できますか?または私は、あなたが変更しているだけで1 'STRING'がある場合、あなたは' updateMessageを() 'を呼び出し、その後、タスクのメッセージにあなたのUIコントロールをバインドすることができます' updateMessage() ' – silversunhunter

+0

@silversunhunterを使用する方法を理解する必要がありますタスクの 'messageProperty()'でリスナーを登録します。より一般的には、UIを更新する呼び出しを 'call()'メソッドに入れて、それぞれが 'Platform.runLater()'でラップされることで、プログレッシブUIアップデートを実行できます。ここでも[documentation](http://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html)を参照してください。 「シーングラフを変更するタスク」の例を参照してください。 –

関連する問題