Accueil / Articles PiApplications. / La plate-forme Java / Java FX

Capture de la fermeture d'une fenêtre FXML.

Il arrive parfois que l'on souhaite appliquer un traitement particulier lors de la fermeture d'une fenêtre. S'il s'agit de la fenêtre principale, cela est assez aisé avec la surcharge de la méthode stop(). Cela n'est pas aussi évident avec une fenêtre FXML quelque soit son mode de lancement (modalité en particulier).

Lorsque vous créez une fenêtre FXML vous écrivez généralement un code de la forme :

    FXMLLoader ldr = new FXMLLoader(getClass().getResource("FXMLMaFenetre.fxml"), resourcesBundle);
    Parent prn = ldr.load();
    FXMLMaFenetreControleur mfc = (FXMLMaFenetreControleur)ldr.getController();
    Stage stg = new Stage();

L'objet le plus important pour nous est ici l'objet de classe Stage car il représente le fond de fenêtre, c'est à dire celui qui reçoit les évènements de l'interface graphique (et du système sous-jacent) et les redistribue aux différents contrôles intégrés à cette fenêtre.

Nous allons nous intéresser à l'un de ces évènements en particulier : onCloseRequest. Cet évènement est reçu dès que l'objet de classe Stage reçoit une demande de fermeture et AVANT que celle-ci ne soit effective. En d'autres termes au bon endroit pour capturer la demande de fermeture sans qu'aucun changement n'y soit encore lié.

Il est possible de fixer un gestionnaire pour cet évènement grâce à la méthode setOnCloseRequest(). Cette méthode attend un objet d'une classe qui implémente l'interface EventHandler. Il s'agit d'une interface fonctionnelle qui peut donc être traitée via une expression lambda plutôt que comme une classe anonyme. En voici un exemple de code :

    stg.setOnCloseRequest(wev ->
    {
      try
      {
        cleanParsedDocumentsSerialization();
        ObservableList<ParsedResult> ols = _tvwFiles.getItems();
        if (! ols.isEmpty())
        {
          ArrayList<ParsedResult> als = new ArrayList<>();
          ols.forEach(prs ->
          {
            als.add(prs);
          });
          serializeParsedDocuments(als);
        }
      }
      catch (IOException ioe)
      {
        LOG.error(ioe);
      }
    });

Dans cet exemple, on capture la fermeture pour sérialiser le contenu d'un contrôle de classe TableView nommé _tvwFiles. Comme l'on ne consomme pas l'évènement, il est propagé et la fermeture intervient immédiatement après l'exécution de ce code.

Si l'on avait simplement voulu ignorer la demande de fermeture de la fenêtre, il aurait suffit de consommer l'évènement dans ce gestionnaire : wev.consume();.

(c) PiApplications 2016