ntro.ca

        • Contrats de classe
        • Liens utiles
        • Calendrier
        • Calendrier groupe 2
        • Calendrier groupes 1, 3
        • Structure du cours
        • Évaluations
        • Matériel à se procurer
        • Les profs
          • Marc-Olivier Tremblay
          • Mathieu Bergeron
        • Module 1.1: installation + trier des cartes
        • Module 1.2: rappels POO
        • Module 1.3: tableau d'objets
        • Examen 1
        • Module 2.1: données JSON
        • Module 2.2: données en Java
        • Module 2.3: récursivité
        • Examen 2
        • Module 3.1: structure générique
        • Module 3.2: efficacité (1)
        • Module 3.3: efficacité (2)
        • Examen 3
        • Module 4.1: liste naïve
        • Module 4.2: liste par tableau
        • Module 4.3: liste chaînée
        • Examen 4
        • Module 5.1: mappage naïf
        • Module 5.2: mappage par hachage
        • Module 5.3: mappage par arbre
        • Examen 5
        • Équipes
          • Horaire groupe 1
          • Horaire groupe 2
          • Horaire groupe 3
          • Groupe 1
          • Groupe 2
          • Groupe 3
        • Projets vedettes 2022
        • Projets vedettes 2023
        • Projets vedettes 2024
        • Projets vedettes 2025
        • Survol
        • Structure
        • Calendrier
        • Calendrier des séances
        • Évaluations
        • Exemples de jeu
        • Exemples de pages
        • Réponses à vos questions
        • Module 1: créer le projet
        • Module 2: concevoir l'application
        • Module 3: vues NtroFx
        • Module 4: modèle et navigation
        • Module 5: ajouter le dorsal, modifier le modèle
        • Module 7: améliorer l'affichage
        • Module 8: jeu en 2d
        • Module 9: client/serveur
        • Module 10: plusieurs instances du même modèle
        • TP1
        • Examen 1
        • TP2
        • Examen 2
        • Projet de fin de session
        • Calendrier
        • Structure du cours
        • Évaluations
        • Contrat de classe
        • Le prof
        • 01: Windows et Word
          • Astuces et raccourcis
        • 02: Word
        • 03: Word
          • Exercice Word: insertion d'éléments spéciaux
          • Exercice Word: tableaux
        • 04: Word
          • Exercice Word: références
          • TP01: Word (15%)
        • 05: PowerPoint
          • TP02: PowerPoint (10%)
        • 06: Examen Word (20%)
        • 07: Excel
        • 08: Excel
        • 09: Excel
          • TP03: Excel (15%)
        • 10: Excel
        • 11: Examen Excel (20%)
        • 12: Access
        • 13: Access
        • 14: Access
        • 15: Examen Access
      • Sondage H2023 (dept. info)
      • Vision H2023 (dept. info)
      • P1) exercices interactifs de lecture
      • P2) transition Excel vers Python
        • Atelier 2: un exemple
      • Jquery
      • Jquery Ui
      • Point de vue sur l'IA
    Les Vues en Ntro et JavaFx
    • Les Vues en Ntro et JavaFx
      • Les fichiers d’une Vue
      • Exemples de fichiers FXML
      • Structure d’une Vue en FXML
      • Exemples de conteneurs JavaFx
      • Quelles sont les balises valides?
      • Le CSS en JavaFx
      • Les traductions en JavaFx
      • Déclarer des Vues en Ntro
      • Charger une Vue avec une tâche viewLoader(...)
      • Créer une Vue avec une tâche create(...)
      • Afficher la Vue racine en Ntro
      • Afficher une page en Ntro

    Les Vues en Ntro et JavaFx #

    Les fichiers d’une Vue #

    • Il y a trois fichiers à fournir pour créer une vue:

    • un fichier .fxml (obligatoire)

    • un fichier .css (optionnel)

    • un fichier .properties qui contient des traductions (optionnel)

    • Le format FXML est une variante de XML spécifique à JavaFx

    • en FXML, on peut décrire la vue avec des balises, un peu comme en HTML

    • p.ex. pour ajouter un bouton: <Button> </Button>

    • Le .css permet de modifier l’apparence des éléments affichés (comme en HTML)

    • Le fichier .properties contient du texte à afficher

    • des fichiers .properties additionnels permettent de supporter d’autres langues

    Exemples de fichiers FXML #

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.layout.StackPane?>
    
    <StackPane xmlns:fx="http://javafx.com/fxml"
        fx:controller="pong.frontal.vues.VueRacine">
    
    </StackPane>
    
    • La première ligne est obligatoire
    <?xml version="1.0" encoding="UTF-8"?>
    
    • Ensuite, il faut importer chaque balise qu’on utilise
    <?import javafx.scene.layout.StackPane?>
    
    • (comme si on importait une classe)

    • La première balise doit avoir les attributs

    1. xmlns:fx

      <StackPane xmlns:fx="http://javafx.com/fxml"
      
      • (c’est comme ça qu’on indique qu’il s’agit de FXML)
    2. fx:controller

          fx:controller="pong.frontal.vues.VueRacine">
      
      • où on déclare la classe Java de la Vue
        • (ce que JavaFx nomme controller, Ntro appelle plutôt la Vue)
    • Autre exemple:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.layout.VBox?>
    <?import javafx.scene.control.Button?>
    
    <VBox xmlns:fx="http://javafx.com/fxml"
        fx:controller="pong.frontal.vues.VueFileAttente">
    
        <Button></Button>
    
    </VBox>
    
    • On voit que dans la balise racine VBox, y a une balise Button

    • En fait, on doit tout mettre dans la balise racine

    • (ou dans une balise qui est dans la balise racine)

    • (ou dans une balise qui est dans une balise qui est dans la balise racine)

    • (etc.)

    Structure d’une Vue en FXML #

    • Chaque balise correspond à un noeud (un élément graphique)

    • Certains noeuds sont des éléments simple (p.ex. un Bouton)

    • D’autres noeuds sont des conteneurs

      • un conteneur est une région rectangulaire qui contient des noeuds
    • Le conteneur est le parent et les noeuds contenus sont les enfants du conteneur

      • un enfant est soit un élément ou un autre conteneur
    • Chaque conteneur est responsable de:

      • placer chaque enfants dans l’espace
      • calculer la taille de chaque enfant
        • (en fonction p.ex. de propriétés comme -fx-min-width et -fx-max-width)

    Exemples de conteneurs JavaFx #

    • StackPane

      • affiche un seul enfant et lui donne toute l’espace
      • NOTES:
        • en fait le StackPane affiche un avant-plan et un ou des arrières plans
        • on va l’utiliser uniquement pour l’avant-plan (un seul enfant)
    • VBox

      • place ses enfants du haut vers le bas, verticalement
    • Il y a en plein d’autre

      • voir la liste des sous-classes de Pane

    Quelles sont les balises valides? #

    • Chaque classe graphique JavaFx est une balise

      • P.ex. la classe Button du paquet javafx.scene.control
      • (et plusieurs autres classes du paquet javafx.scene)
    • On peut créer une balise personalisée en héritant d’une classe graphique

      • P.ex. class MonBouton extends Button va créer la balise <MonBouton>
    • Une bonne façon d’explorer le FXML est d’utiliser l’outil SceneBuilder

      • C’est un outil graphique pour créer des Vues en FXML
      • L’outil sauvegarde en ..fxml
      • On peut alors inspecter les balises utilisées
    • ATTENTION

      • il faut utiliser l’extension ..fxml pour utiliser SceneBuilder
      • l’outil SceneBuilder a aussi tendance à générer du .fxml touffu
      • SVP ne pas utiliser ce .fxml directement dans votre projet

    Le CSS en JavaFx #

    • Comme pour HTML, le CSS de JavaFx a les notions de

      • sélecteur, p.ex: #id et .class
      • propriétés, p.ex. -fx-backgroundcolor:gray
    • ATTENTION

      • Les propriétés CSS ne sont pas les mêmes qu’en HTML
        • En JavaFx, les propriétés commencent par -fx-
        • Voici le guide complet du CSS en JavaFX
          • https://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html
    • Pour utiliser le CSS, il faut ajouter des attributs aux balises

      • id pour l’identifiant CSS
      • styleClass pour spécifier la class CSS (et non class)
    • Par exemple

      <VBox xmlns:fx="http://javafx.com/fxml"
          fx:controller="pong.frontal.vues.VueFileAttente"
          styleClass="conteneur"
          id="vue-file-attente">
      
          <Button
              styleClass="gros-bouton"
              id="bouton-s-inscrire">
          </Button>
      
      </VBox>
      
    • Finalement, il faut déclarer votre CSS dans le Frontal

    public class FrontalPong implements FrontendFx {
    
        @Override
        public void registerViews(ViewRegistrarFx registrar) {
    
            registrar.registerStylesheet("/style/dev.css");
            //registrar.registerStylesheet("/style/prod.css");
        }
    }
    

    Les traductions en JavaFx #

    • Un fichier .properties contient des paires variable/valeur de la forme

      sInscrire=S'inscrire
      retour=Retour
      
      • NOTES:
        • la variable est avant le = (p.ex. sInscrire et retour)
        • la valeur est après le = (sans ")
    • On peut utiliser ce texte en FXML avec %variable

      <?xml version="1.0" encoding="UTF-8"?>
      
      <?import javafx.scene.layout.VBox?>
      <?import javafx.scene.control.Button?>
      
      <VBox xmlns:fx="http://javafx.com/fxml"
          fx:controller="pong.frontal.vues.VueFileAttente">
      
          <Button
              text="%sInscrire">
          </Button>
      
      </VBox>
      
    • Il faut déclarer des fichier .properties dans le Frontal:

      public class FrontalPong implements FrontendFx {
      
          @Override
          public void registerViews(ViewRegistrarFx registrar) {
      
              // Langue par défaut
              registrar.registerDefaultLocale(Ntro.buildLocale("fr"));
      
              // Traductions
              registrar.registerTranslations(Ntro.buildLocale("fr"), "/traductions/fr.properties");
              registrar.registerTranslations(Ntro.buildLocale("en"), "/traductions/en.properties");
          }
      }
      

    Déclarer des Vues en Ntro #

    • Créer d’abord une classe qui hérite de ViewFx

      public class VueRacine extends ViewFx {
      
          @Override
          public void initialize() {
      
          }
      }
      
      • NOTES:
        • la méthode initialize est requise
        • on va l’utiliser dans le module 4
    • Déclarer la Vue dans le Frontal

      import pong.frontal.vues.VueRacine;
      
      public class FrontalPong implements FrontendFx {
      
          @Override
          public void registerViews(ViewRegistrarFx registrar) {
      
              registrar.registerView(VueRacine.class, "/vues/racine.fxml");
          }
      }
      
    • S’assurer que l’attribut fx:controller est correct:

          fx:controller="pong.frontal.vues.VueRacine">
      
      • doit être le nom complet de la classe, comme dans un import

        import pong.frontal.vues.VueRacine;
        
    • (Optionnel) on peut aussi déclarer un fichier CSS

      registrar.registerStylesheet("/style/dev.css");
      
    • (Optionnel) on peut aussi déclarer des traductions

      registrar.registerTranslations(Ntro.buildLocale("fr"), "/traductions/fr.properties");
      registrar.registerTranslations(Ntro.buildLocale("en"), "/traductions/en.properties");
      

    Charger une Vue avec une tâche viewLoader(...) #

    • S’assurer d’enregistrer la Vue dans le Frontal

              registrar.registerView(VueRacine.class, "/vues/racine.fxml");
      
    • Une fois la vue enregistrée, Ntro va créer la tâche

      • viewLoader(VueRacine.class)
    • Ensuite, on peut utiliser la tâche dans le graphe de tâches

    Créer une Vue avec une tâche create(...) #

    • On a besoin d’un objet ViewLoader<VueRacine> pour créer la Vue

    • On ajoute une dépendance à une tâche viewLoader(VueRacine.class)

      tasks.task(create(VueRacine.class))
      
      	 .waitsFor(viewLoader(VueRacine.class))
      
      	 .executesAndReturnsValue(inputs -> {
      
      		 ViewLoader<VueRacine> viewLoader = inputs.get(viewLoader(VueRacine.class));
      
      		 VueRacine vueRacine = viewLoader.createView();
      
      		 return vueRacine;
      	 });
      
      • NOTES:
        • une tâche de type create(...) retourne un résultat
        • comme la tâche est de type create(VueRacine.class), il faut retourner un objet de type VueRacine

    Afficher la Vue racine en Ntro #

    • La Vue racine s’affiche à même la fenêtre

    • On ajoute une dépendance à la tâche window()

      tasks.task("installerVueRacine")
      
      	  .waitsFor(window())
      
      	  .waitsFor(created(VueRacine.class))
      
      	  .executes(inputs -> {
      
      		  VueRacine vueRacine = inputs.get(created(VueRacine.class));
      		  Window    window    = inputs.get(window());
      
      		  window.installRootView(vueRacine);
            });
      

    Afficher une page en Ntro #

    • Une page (ou sous-vue) va s’afficher à l’intérieur de la VueRacine

    • Dans la VueRacine, on a besoin d’une méthode qui installe une sous-vue

      public class VueRacine extends ViewFx {
      
          public void afficherSousVue(ViewFx sousVue) {
              Pane racineSousVue = sousVue.rootNode();
      
              rootNode().getChildren().clear();
              rootNode().getChildren().add(racineSousVue);
          }
      }
      
      • NOTES:
        • rootNode() retourne la conteneur racine (ou balise racine) de la vue
        • notre VueRacine place la sous-vue directement à la racine
    • Ensuite, on a une tâche pour afficher la page

      tasks.task("installerVueFileAttente")
      
      	  .waitsFor(created(VueRacine.class))
      
      	  .waitsFor(created(VueFileAttente.class))
      
      	  .executes(inputs -> {
      
      		  VueRacine      vueRacine      = inputs.get(created(VueRacine.class));
      		  VueFileAttente vueFileAttente = inputs.get(created(VueFileAttente.class));
      
      		  vueRacine.afficherSousVue(vueFileAttente);
      
      	  });
      

    Ou avec des groupes de tâches, comme dans le tutoriel:

    Creative Commons License Creative Commons Attribution Creative Commons ShareAlike
    • Les Vues en Ntro et JavaFx
      • Les fichiers d’une Vue
      • Exemples de fichiers FXML
      • Structure d’une Vue en FXML
      • Exemples de conteneurs JavaFx
      • Quelles sont les balises valides?
      • Le CSS en JavaFx
      • Les traductions en JavaFx
      • Déclarer des Vues en Ntro
      • Charger une Vue avec une tâche viewLoader(...)
      • Créer une Vue avec une tâche create(...)
      • Afficher la Vue racine en Ntro
      • Afficher une page en Ntro