如何在Java FX控制器中等待窗口的返回值?

时间:2016-02-16 13:44:34

标签: multithreading javafx

我有一个java fx控制器类,有do方法,我希望等到我从另一个屏幕收集信息。请参阅以下代码以更好地理解。这个do()方法是从我的Javafx Application类的start()方法调用的。

@FXML
public void do() throws Exception {

    FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("/fxml/myPage.fxml"));
    Parent root = (Parent)fxmlLoader.load();
    Scene mainScene = new Scene(root);
    Stage stage = new Stage();  
    stage.setHeight(500);
    stage.setWidth(400);
    stage.setScene(mainScene);
    stage.setTitle("Provide input");        
    stage.show();       
    System.out.println(Thread.currentThread().getName() +"returned");
}

所以这里我从我的应用程序调用do方法,并希望do()返回我从myPage屏幕捕获的值。在这里,我无论如何都找不到等待。如果我在调用show()之后等待,则永远不会显示屏幕。 JavaFX希望我从这个函数返回,然后只有我看到屏幕,我还在控制台上看到“返回”消息。

我可以编写另一个方法,这个新页面的控制器在获取输入后会调用但是我无论如何从do()方法返回。我怎么才待在这里?我试图打开新的线程然后加载fxml但它给出了“Not Same Thread”错误。我看到javaFX应用程序类的start()方法甚至需要控制回显示屏幕。

1 个答案:

答案 0 :(得分:1)

你可以使用stage.showAndWait(),它基本上会按照它在框中所说的那样做:显示舞台并阻止执行直到隐藏舞台:

@FXML
public void do() throws Exception {

    FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("/fxml/myPage.fxml"));
    Parent root = (Parent)fxmlLoader.load();
    Scene mainScene = new Scene(root);
    Stage stage = new Stage();  
    stage.setHeight(500);
    stage.setWidth(400);
    stage.setScene(mainScene);
    stage.setTitle("Provide input");        
    stage.showAndWait();     
    // get results of input here...  
    System.out.println(Thread.currentThread().getName() +"returned");
}

或者您可以注册隐藏舞台时调用的侦听器,并处理其中的输入:

@FXML
public void do() throws Exception {

    FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("/fxml/myPage.fxml"));
    Parent root = (Parent)fxmlLoader.load();
    Scene mainScene = new Scene(root);
    Stage stage = new Stage();  
    stage.setHeight(500);
    stage.setWidth(400);
    stage.setScene(mainScene);
    stage.setTitle("Provide input");   
    stage.setOnHidden(e -> {
        // process input here...
    });     
    stage.show();       
    System.out.println(Thread.currentThread().getName() +"returned");
}

此版本不会阻止执行,因此您的do()方法将立即退出,但是当新阶段隐藏时,将调用处理程序中的代码块。