ntro.ca

        • Contrats de classe
        • Liens utiles
        • Calendrier
        • Calendrier groupe 3
        • Calendrier groupes 1, 2
        • 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
          • URL dépôt Git à remettre
        • Module 1.3: tableau d'objets
        • Examen 1
        • Validation des ateliers
        • Module 2.1: données JSON
        • Module 2.2: données en Java
        • Module 2.3: récursivité
        • Examen 2
        • Validation des ateliers
        • Module 3.1: structure générique
        • Module 3.2: efficacité (1)
        • Module 3.3: efficacité (2)
        • Examen 3
        • Validation des ateliers
        • Module 4.1: liste naïve
        • Module 4.2: liste par tableau
        • Module 4.3: liste chaînée
        • Examen 4
        • Validation des ateliers
        • Module 5.1: mappage naïf
        • Module 5.2: mappage par hachage
        • Module 5.3: mappage par arbre
        • Examen 5
        • Validation des ateliers
        • Travail de rattrapage
        • Projets vedettes
          • Contrat gr1
          • Contrat gr2
          • Contrat gr3
        • Survol
        • Structure
        • Calendrier semaines
          • Calendrier gr1
          • Calendrier gr2
          • Calendrier gr3
        • Utilisation IA
        • Évaluations
        • Exemples de pages
        • Exemples de jeu
        • Jeux choisis
        • 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
        • Examen 1
        • Examen 2
        • Calendrier
        • Évaluations
        • Structure du cours
        • Contrat de classe
        • Le prof
        • 01: Windows et Word
          • Astuces et raccourcis
        • 02: Word
          • Exercice Word: insertion d'éléments spéciaux
          • Exercice Word: tableaux
        • 03: Word
          • Exercice Word: références
          • TP01: Word (15%)
        • 04: Word
        • 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
      • Index
      • Point de vue sur l'IA
    Tutoriel 4: analyse
    • Tutoriel 4: analyse
      • Comparer le comportement de dep03 et dep04
      • Comparer les graphes de tâches de dep03 et dep04
      • Comparer les fichiers dep03 et dep04
        • Nouveaux fichiers dans dep04
        • Fichiers différents
      • Exemple d’analyse d’un nouveau fichier: ModeleA
        • Attributs ModeleA
        • À quoi sert methodeC?
        • Qu’est-ce que ValeurA?
      • Exemple d’analyse d’un fichier modifié: VueA

    Tutoriel 4: analyse #

    Comparer le comportement de dep03 et dep04 #

    dep03

    dep04

    $ sh gradlew dep03

    $ sh gradlew dep04

    • Affiche une vue simple, avec mise en forme de base
    • Navigation entre deux vues
    • Afficher un modèle en mode texte

    Comparer les graphes de tâches de dep03 et dep04 #

    dep03/_storage/graphs/frontend.png

    dep04/_storage/graphs/frontend.png

    • Groupe de tâches TachesB avec une tâche qui affiche la fenêtre et une autre tâche (qui installe la Vue?)

    • Groupe de tâches ViewLoaders (qui charge les fichiers .xml et/ou .css pour la Vue?)

    • Groupe de tâches TachesA (pour créer la vue VueA à partir du ViewLoader?)

    • Groupe de tâches ViewLoaders charge les fichiers de deux vues de plus

    • Groupe de tâches TachesA permet de créer deux vues de plus

    • Groupe de tâches TachesB affiche la fenêtre et choisit la première vue

    • Groupe de tâches TachesC réagit à des événements (probalement pour naviguer d’une vue à l’autre)

    • Groupe de tâches TachesD observe un modèle (probablement pour l’afficher)

    Comparer les fichiers dep03 et dep04 #

    • Comparer les répertoires dep03/src et dep04/src avec VSCode:

    Nouveaux fichiers dans dep04 #

    ModeleA et ValeurA

    Classes pour un modèle et une valeur personnalisée

    EvtA et EvtB

    Sûrement les événements de navigation:

    • EvtA pour afficher la vue A?
    • EvtB pour afficher la vue B?

    TachesC

    Semblent être les tâches de navigation (tâches pour réagir aux événements A et B)

    TachesD

    Semble contenir la tâche qui observe le modèle (et l’affiche?)

    VueB

    La deuxième vue qui s’affiche

    VueRacine

    Probablement une vue qui sert à afficher une page (une autre Vue)

    Fichiers différents #

    TachesA

    Sûrement parce qu’on charge 2 vues de plus: VueB et VueRacine

    TachesB

    Peut-être pour installer la VueRacine dans le fenêtre

    VueA

    Comportement du bouton qui change de page?

    FrontalDepart et AppDepart

    Sûrement pour déclarer les nouvelles classes: événements, modèle, valeur, nouvelles vues, etc.

    vue_a.fxml

    Bouton en haut du Label plutôt que le contraire

    Exemple d’analyse d’un nouveau fichier: ModeleA #

    Voici le ModeleA

    public class ModeleA implements Model, WatchJson, WriteObjectGraph {
    
        private boolean attrA = false;
        private double  attrB = 10.0;
    
        private List<ValeurA> valeurs = new ArrayList<>();
    
        public void methodeC(VueA vueA) {
    
            vueA.methodeA(this.toString());
        }
        
        public String toString() {
    
            StringBuilder builder = new StringBuilder();
    
            builder.append("attrA: " + attrA);
            builder.append(System.lineSeparator());
    
            builder.append("attrB: " + attrB);
            builder.append(System.lineSeparator());
            builder.append(System.lineSeparator());
            
            builder.append("valeurs: ");
            builder.append(System.lineSeparator());
    
            for(ValeurA valeur : valeurs) {
    
                builder.append("  ");
                builder.append(valeur.toString());
                builder.append(System.lineSeparator());
            }
    
            return builder.toString();
        }
    
    }
    

    Attributs ModeleA #

    • on a attrA et attrB
    • on a une liste où chaque item est un objet de type ValeurA

    À quoi sert methodeC? #

    • La méthode reçoit en paramètre une référence à la VueA, convertit l’objet courant en chaîne, puis appelle VueA.methodeA

      public class ModeleA implements Model, WatchJson, WriteObjectGraph {
      
          //...
      
          public void methodeC(VueA vueA) {
      
              vueA.methodeA(this.toString());
          }
      
    • À quoi sert la methodeA?

    • En VSCode, placer le curseur sur methodeA et faire F12 (Atteindre la définition)

      • autre option: Ctrl+Clic sur methodeA
    • La VueA.methodeA est comme suit:

      public class VueA extends ViewFx {
      
          @FXML
          private Label labelA;
      
          // ...
      
          public void methodeA(String paramA) {
              labelA.setText(paramA);
          }
      
      }
      
      • affiche du texte dans un Label

      • renommages possible pour VueA.methodeA:

        • afficher
        • afficherTexte
        • afficherEnBas (de la page)
    • En VSCode, revenir à ModeleA: où est appelé la methodeC?

    • En VSCode, placer le curseur sur methodeC et faire Alt+Maj+H

      • autre option: Clic-droit => Afficher la hiérarchie des appels
    • On sait maintenant que methodeC est appelée dans la tacheD1

    • La tacheD1 devrait s’exécuter à chaque fois que le modèle est modifié

      • à cause du waitsFor(modified(ModeleA))
    • Vérifier en observant la console:

    • Donc la tacheD1 et ModeleA.methodeC servent à afficher le modèle en mode texte sur la VueA dès que le modèle est modifié

    • Renommages possibles pour methodeC

      • afficher
      • afficherSur
      • afficherEnModeTexte
      • afficherEnModeTexteSur

    Qu’est-ce que ValeurA? #

    En VSCode, placer le curseur sur ValeurA et faire F12 (Atteindre la définition)

    • autre option: Ctrl+Clic sur ValeurA

    VSCode va ouvrir ValeurA:

    public class ValeurA implements ModelValue {
        
        private String attrA;
        private int    attrB;
    
        @Override
        public String toString() {
            return "[" + attrA + ", " + String.format("%02d", attrB) + "]";
        }
    
    }
    
    • on a attrA et attrB

    • on peut s’attendre à des données du genre:

      {
        "_C": "ValeurA",
        "attrB": 8,
        "attrA": "str06"
      }
      

      ou encore:

      {
        "_C": "ValeurA",
        "attrB": 19,
        "attrA": "str05"
      }
      

      ou encore:

      {
        "_C": "ValeurA",
        "attrB": 4,
        "attrA": "str03"
      }
      
    • la méthode toString retourne une chaîne avec la valeur des deux attributs:

    Données

    retour de toString

    {
      "_C": "ValeurA",
      "attrB": 8,
      "attrA": "str06"
    }
    

    "[str06, 08]"

    {
      "_C": "ValeurA",
      "attrB": 19,
      "attrA": "str05"
    }
    

    "[str05, 19]"

    {
      "_C": "ValeurA",
      "attrB": 4,
      "attrA": "str03"
    }
    

    "[str03, 04]"

    Exemple d’analyse d’un fichier modifié: VueA #

    Ajouts à la VueA

    • ajout d’attributs @FXML pour récupérer les contrôles

      • labelA
      • boutonA
    • ajout de validation qu’on a bien récupéré le contrôle, p.ex.

      • Ntro.assertNotNull(labelA)
    • déclenché un événement Ntro quand le boutonA est appuyé:

      boutonA.setOnAction(evtFx -> {
      
          Ntro.newEvent(EvtB.class).trigger();
      
      });
      
    • où est-ce que l’événement EvtB est capté?

    • En VSCode, placer le curseur sur EvtB et faire Maj+F12

      • autre option: clic-droit => Atteindre les références
    • On voit que EvtB apparaît dans une des TachesC qui fait un waitsFor(EvtB)

    • Cliquer sur le waitsFor(EvtB) pour afficher directement la bonne tâche, tacheC2:

      private static void tacheC2(FrontendTasks subTasks) {
      
          subTasks.task("tacheC2")
      
               .waitsFor(event(EvtB.class))
      
               .waitsFor(created(VueRacine.class))
      
               .waitsFor(created(VueB.class))
      
               .executes(inputs -> {
      
                   var objD = inputs.get(event(EvtB.class));
                   var objE = inputs.get(created(VueRacine.class));
                   var objF = inputs.get(created(VueB.class));
      
                   objD.methodeA(objE, objF);
      
               });
      
      }
      
    • C’est la tâche qui réagit à l’EvtB et afficher la VueB

    • Renommages possibles:

      • EvtB => EvtAfficherVueB
    • Vérifier en observant la console

    Creative Commons License Creative Commons Attribution Creative Commons ShareAlike
    • Tutoriel 4: analyse
      • Comparer le comportement de dep03 et dep04
      • Comparer les graphes de tâches de dep03 et dep04
      • Comparer les fichiers dep03 et dep04
        • Nouveaux fichiers dans dep04
        • Fichiers différents
      • Exemple d’analyse d’un nouveau fichier: ModeleA
        • Attributs ModeleA
        • À quoi sert methodeC?
        • Qu’est-ce que ValeurA?
      • Exemple d’analyse d’un fichier modifié: VueA