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
        • Module 5: ajouter le dorsal, modifier le modèle
        • Guide de style 4F5
        • TP1
        • 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 5: projet pong minimal
    • Tutoriel 5: projet pong minimal
      • Étape 1) créer le projet pong05 à partir de dep05
      • Étape 2) implanter le bon modèle
      • Vérifier l’état courant du projet
      • Étape 3) implanter le bon message
      • Vérifier l’état courant du projet
      • Étape 4) adapter MaquetteDepart
      • Étape 5) adapter les vues
        • Modifier les fichiers .properties
        • Adapter le fichier vue_a.fxml
        • Adapter le fichier vue_b.fxml
        • Ajouter un fichier prod.css et le déclarer dans FrontalPong.java
      • Vérifier le comportement et l’affichage

    Tutoriel 5: projet pong minimal #

    Étape 1) créer le projet pong05 à partir de dep05 #

    1. Dans un GitBash à la racine du dépôt Git

      $ cp -rf dep05 pong05
      
    2. Modifier settings.gradle pour ajouter l’include

      include 'pong05'
      
    3. Vérifier que pong05 s’exécute

      $ sh gradlew pong05
      
    4. Dans VSCode, faire un clean workspace pour afficher le projet pong05

    Étape 2) implanter le bon modèle #

    1. Avec F2, renommer la classe

      • ModeleA => ModeleFileAttente
    2. Avec F2, renommer la classe

      • ValeurA => PartieEnFile
    3. Modifier ModeleFileAttente selon le document de conception:

      public class ModeleFileAttente implements Model, WatchJson, WriteObjectGraph {
      
          private int  prochainId = 0;
      
          private List<PartieEnFile> parties = new ArrayList<>();
      
          // ...
      
    4. Modifier ModeleFileAttente.methodeA avec des valeurs temporaires

      public void methodeA(String paramA, int paramB) {
      
          parties.add(new PartieEnFile(String.valueOf(prochainId++), 
                                       null, 
                                       paramA, 
                                       paramB, 
                                       null, 
                                       null, 
                                       0));
      }
      
    5. Modifier ModeleFileAttente.toString

      public String toString() {
      
          StringBuilder builder = new StringBuilder();
      
          builder.append("prochainId: " + prochainId);
          builder.append(System.lineSeparator());
          builder.append(System.lineSeparator());
      
          builder.append("parties: ");
          builder.append(System.lineSeparator());
      
          for(PartieEnFile valeur : parties) {
      
              builder.append("  ");
              builder.append(valeur.toString());
              builder.append(System.lineSeparator());
          }
      
          return builder.toString();
      }
      
    6. Modifier PartieEnFile selon le document de conception:

      public class PartieEnFile implements ModelValue {
      
          private String idPartie;
      
          private String idJoueurA;
          private String nomJoueurA;
          private int    scoreJoueurA;
      
          private String idJoueurB;
          private String nomJoueurB;
          private int    scoreJoueurB;
      
          // ...
      
    7. Modifier le constructeur:

      public PartieEnFile(String idPartie, 
                          String idJoueurA, 
                          String nomJoueurA, 
                          int scoreJoueurA, 
                          String idJoueurB, 
                          String nomJoueurB, 
                          int scoreJoueurB) {
      
          this.idPartie = idPartie;
          this.idJoueurA = idJoueurA;
          this.nomJoueurA = nomJoueurA;
          this.scoreJoueurA = scoreJoueurA;
          this.idJoueurB = idJoueurB;
          this.nomJoueurB = nomJoueurB;
          this.scoreJoueurB = scoreJoueurB;
      }
      
    8. Modifier PartieEnFile.toString

      @Override
      public String toString() {
      
          StringBuilder builder = new StringBuilder();
      
          builder.append(nomJoueurA);
          builder.append(" Vs ");
          if(nomJoueurB == null){
              builder.append("???");
          }else{
              builder.append(nomJoueurB);
          }
      
          builder.append("  ");
          builder.append(scoreJoueurA);
          builder.append("-");
          builder.append(scoreJoueurB);
      
          return builder.toString();
      }
      

    Vérifier l’état courant du projet #

    1. Dans un GitBash à la racine du dépôt Git

      $ sh gradlew pong05
      

    Étape 3) implanter le bon message #

    1. Avec F2, renommer la classe

      • MsgA => MsgAjouterPartie
    2. Modifier les attributs du message

      public class MsgAjouterPartie extends Message<MsgAjouterPartie> {
      
          private String idJoueurA;
          private String nomJoueurA;
          private int    scoreJoueurA;
      
          private String idJoueurB;
          private String nomJoueurB;
          private int    scoreJoueurB;
      
    3. Avec Ctrl+., générer les setters

      public void setIdJoueurA(String idJoueurA) {
          this.idJoueurA = idJoueurA;
      }
      
      public void setNomJoueurA(String nomJoueurA) {
          this.nomJoueurA = nomJoueurA;
      }
      
      public void setScoreJoueurA(int scoreJoueurA) {
          this.scoreJoueurA = scoreJoueurA;
      }
      
      public void setIdJoueurB(String idJoueurB) {
          this.idJoueurB = idJoueurB;
      }
      
      public void setNomJoueurB(String nomJoueurB) {
          this.nomJoueurB = nomJoueurB;
      }
      
      public void setScoreJoueurB(int scoreJoueurB) {
          this.scoreJoueurB = scoreJoueurB;
      }
      
    4. Adapter les setters pour retourner this

      public MsgAjouterPartie setIdJoueurA(String idJoueurA) {
          this.idJoueurA = idJoueurA;
          return this;
      }
      
      public MsgAjouterPartie setNomJoueurA(String nomJoueurA) {
          this.nomJoueurA = nomJoueurA;
          return this;
      }
      
      public MsgAjouterPartie setScoreJoueurA(int scoreJoueurA) {
          this.scoreJoueurA = scoreJoueurA;
          return this;
      }
      
      public MsgAjouterPartie setIdJoueurB(String idJoueurB) {
          this.idJoueurB = idJoueurB;
          return this;
      }
      
      public MsgAjouterPartie setNomJoueurB(String nomJoueurB) {
          this.nomJoueurB = nomJoueurB;
          return this;
      }
      
      public MsgAjouterPartie setScoreJoueurB(int scoreJoueurB) {
          this.scoreJoueurB = scoreJoueurB;
          return this;
      }
      
    5. Modifier l’appel à la methodeA

    6. Utiliser Ctrl+. pour modifier la signature de la methodeA:

    7. Finaliser le code de ModeleFileAttente.methodeA

      public void methodeA(String idJoueurA, 
                           String nomJoueurA, 
                           int scoreJoueurA, 
                           String idJoueurB, 
                           String nomJoueurB, 
                           int scoreJoueurB) {
      
          parties.add(new PartieEnFile(String.valueOf(prochainId++), 
                                      idJoueurA, 
                                      nomJoueurA, 
                                      scoreJoueurA, 
                                      idJoueurB, 
                                      nomJoueurB, 
                                      scoreJoueurB));
      }
      
    8. Modifier la création du message dans la VueA

      boutonB.setOnAction(evtFx -> {
      
          Ntro.newMessage(MsgAjouterPartie.class)
              .setNomJoueurA(MaquetteDepart.chaineAuHasard())
              .setScoreJoueurA(MaquetteDepart.entierAuHasard())
              .setNomJoueurB(MaquetteDepart.chaineAuHasard())
              .setScoreJoueurB(MaquetteDepart.entierAuHasard())
              .send();
      });
      

    Vérifier l’état courant du projet #

    1. Dans un GitBash à la racine du dépôt Git

      $ sh gradlew pong05
      

    Étape 4) adapter MaquetteDepart #

    1. Avec F2, renommer la classe

      • MaquetteDepart => MaquettePartie
    2. Modifier le code de MaquetteDepart

      public class MaquettePartie {
      
          private static String idJoueur = "alice";
      
          public static String idJoueur() {
      
              List<String> choixDeId = List.of("alice", 
                                               "bob", 
                                               "chaaya", 
                                               "dominic", 
                                               "élisabeth", 
                                               "firas", 
                                               "gregson",
                                               "mehdi",
                                               "louis",
                                               "marcel",
                                               "ashwin",
                                               "ichiro",
                                               "jun");
      
              idJoueur = Ntro.random().choice(choixDeId);
      
              return idJoueur;
      
          }
      
          public static String nomJoueur() {
              return idJoueur.substring(0,1).toUpperCase() + idJoueur.substring(1);
          }
      
          public static int scoreAuHasard() {
              return Ntro.random().nextInt(10);
          }
      }
      
    3. Modifier l’envoi du message dans VueA

      boutonB.setOnAction(evtFx -> {
      
          Ntro.newMessage(MsgAjouterPartie.class)
              .setIdJoueurA(MaquettePartie.idJoueur())
              .setNomJoueurA(MaquettePartie.nomJoueur())
              .setScoreJoueurA(MaquettePartie.scoreAuHasard())
              .setIdJoueurB(MaquettePartie.idJoueur())
              .setNomJoueurB(MaquettePartie.nomJoueur())
              .setScoreJoueurB(MaquettePartie.scoreAuHasard())
              .send();
      });
      

    Étape 5) adapter les vues #

    Modifier les fichiers .properties #

    • fr.properties

      ajouter=Ajouter
      jouer=Jouer
      quitter=Quitter partie
      
    • en.properties

      ajouter=Add
      jouer=Play
      quitter=Exit Game
      

    Adapter le fichier vue_a.fxml #

    1. Modifier les %var des boutons

      <Button                                    
          fx:id="boutonA"
          text="%jouer" />                       <!-- modifier -->
      
      <!-- ... -->
      
      
      <Button                                    
          fx:id="boutonB"
          text="%ajouter" />                       <!-- modifier -->
      

    Adapter le fichier vue_b.fxml #

    1. Retirer le Label et modifier le %var du bouton

      <!-- ... -->
      
      <Label
          styleClass="label"
          text="%texteA">
      </Label>                                      <!-- retirer -->
      
      <Pane styleClass="espacement,moyen"/>         <!-- retirer -->
      
      <Button 
          fx:id="boutonQuitter" 
          text="%quitter">
      </Button>                                     <!-- modifier -->
      

    Ajouter un fichier prod.css et le déclarer dans FrontalPong.java #

    1. Télécharger le fichier prod.css et le copier dans pong04/src/main/resources/style

    2. Dans FrontalPong.java, modifier la déclaration du CSS:

      //registrar.registerStylesheet("/style/dev.css");
      registrar.registerStylesheet("/style/prod.css");
      

    Vérifier le comportement et l’affichage #

    1. Effacer le modèle actuel

      $ rm -rf pong05/_storage/models
      
    2. Démarrer avec un modèle vide

      $ sh gradlew pong05
      
    Creative Commons License Creative Commons Attribution Creative Commons ShareAlike
    • Tutoriel 5: projet pong minimal
      • Étape 1) créer le projet pong05 à partir de dep05
      • Étape 2) implanter le bon modèle
      • Vérifier l’état courant du projet
      • Étape 3) implanter le bon message
      • Vérifier l’état courant du projet
      • Étape 4) adapter MaquetteDepart
      • Étape 5) adapter les vues
        • Modifier les fichiers .properties
        • Adapter le fichier vue_a.fxml
        • Adapter le fichier vue_b.fxml
        • Ajouter un fichier prod.css et le déclarer dans FrontalPong.java
      • Vérifier le comportement et l’affichage