2017-08-16 49 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),例如示例“修改场景图的任务”。 –

相关问题