2017-08-16 48 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

的基本思路是

  • 創建Taskcall()方法做任何你需要在後臺線程做
  • 如果你有什麼要對FX應用程序線程執行時,任務完成後,使用onSucceeded處理程序,該程序在call()方法完成後調用(在FX應用程序線程上)
  • call()次方法完成,無論是從它返回被設置爲任務的value,這樣你就可以調用getValue()看什麼返回
  • 創建從任務線程,並調用start()執行它

所以在你的情況下,這只是看起來像

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

這是開始點擊!謝謝。還有一個問題。如果我想在任務內部運行幾個方法,我可以使用'postMessage'方法對每個方法的響應更新GUI?或者我需要弄清楚如何使用'updateMessage()' – silversunhunter

+0

@silversunhunter如果只有一個你正在改變的String,你可以調用'updateMessage()',然後將你的UI控件綁定到任務的消息,或者向任務的'messageProperty()'註冊一個監聽器。更一般地說,你可以通過在你的'call()'方法中放置更新UI的調用來執行漸進式UI更新,每個方法都包裝在'Platform.runLater()'中。再次請參閱[documentation](http://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html),例如示例「修改場景圖的任務」。 –

相關問題