Comment attendre dans le contrôleur Java FX pour la valeur de retour de la fenêtre?


J'ai une classe de contrôleur java fx ayant la méthode do, où je souhaite attendre jusqu'à ce que je collecte des informations à partir d'un autre écran. Voir le code ci-dessous pour mieux comprendre. Cette méthode do () est appelée à partir de la méthode start () de ma classe d'application Javafx.

@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");
}

Donc, ici, j'appelle la méthode do à partir de mon application et souhaite que do() me renvoie la valeur que je capture à partir de l'écran MyPage. Ici, je ne trouve pas de toute façon d'attendre. Si je mets wait après l'appel à show (), l'écran ne s'affiche jamais. JavaFX attendre que je reviens de cette fonction et alors seulement je vois l'écran et je vois aussi le message "Retourné" sur la console.

Je peux écrire une autre méthode que le contrôleur de cette nouvelle page appellera après avoir récupéré l'entrée, mais je reviens de toute façon de ma méthode do (). Comment puis-je rester ici seule? J'ai essayé d'ouvrir un nouveau Thread, puis de charger fxml mais cela donne une erreur "Pas le même Thread". Je vois que même la méthode start () de la classe d'application JavaFX doit récupérer le contrôle pour afficher l'écran.

Author: James_D, 2016-02-16

1 answers

Vous pouvez soit utiliser stage.showAndWait() qui fera essentiellement ce qu'il dit sur la boîte: afficher la scène et bloquer l'exécution jusqu'à ce que la scène soit cachée:

@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");
}

Ou vous pouvez enregistrer un écouteur qui est appelé lorsque la scène est masquée et traiter l'entrée:

@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");
}

Cette version ne bloquera pas l'exécution, donc votre méthode do() se quittera immédiatement, mais le bloc de code dans le gestionnaire sera appelé lorsque la nouvelle étape se masquera.

 1
Author: James_D, 2016-02-16 13:55:50