Projet Warriors :
IX. Ajout d’une interface graphique utilisateur
Formateur : T. Carron Modalités :
● Travail en autonomie
● Production individuelle
● Durée : 1 jour pour cette partie
3 jours pour rendre graphique l’ensemble de l’application Warriors
Objectifs de l’activité :
● Apprendre à créer une interface graphique utilisateur (GUI)
Prérequis :
•
Base de java et connaissance de l’approche Orientée ObjetLivrables :
● Code du projet « indépendant » du jour à déposer sur github.
● Glossaire enrichi des différentes syntaxes utilisées. Vous compléterez votre glossaire avec les principaux types de collections. Un glossaire des différentes syntaxes utilisées est à déposer sur votre gist.
Ressources :
● Structurer en MVC : https://www.youtube.com/watch?v=6ZN3-pKU8e4 (au moins les 2.40 premières minutes !)
● Barre de menu et menu : https://baptiste-
wicht.developpez.com/tutoriels/java/swing/debutant/?page=menus
● SpringLayout :
● https://examples.javacodegeeks.com/java-swing-layouts-example/ > 2.7
● http://roger.neel.free.fr/langages/cours_htm/coursjava/swing_springlayout.html
● Maquettes / Mockups (outils) :
● https://korben.info/18-outils-gratuits-mockups.html
● https://www.blogduwebdesign.com/logiciels-wireframe-prototype/
● https://graphiste.com/blog/outils-creer-wireframes-mockups
Et comme avant:
● CodeCademy https://www.codecademy.com/en/courses/learn-java/lessons/data- structures/exercises/data-structures
● Openclassrooms https://openclassrooms.com/courses/apprenez-a-programmer- en-java/les-collections-d-objets
● Tutoriel d’Oracle pour Java
http://docs.oracle.com/javase/tutorial/java/index.html
Hypothèse :
On a un jeu en ligne de commande qui fonctionne et dont on devra imaginer l’interface. On va partir d’un nouveau projet et on intègrera les classes déjà faites àmesure.
NB : Au début (Jour 1), on ne devrait pas avoir besoin d’utiliser les classes déjà faites donc ne vous préoccupez pas de votre avancement antérieur.
Etape 9
itération 9
Un projet structuré en MVC
Liste des étapes du jour en rapide
(pour que vous ayez une vue globale):
Etapes :0/ Structurer en MVC : https://www.youtube.com/watch?v=6ZN3-pKU8e4 (au moins les 2.40 premières minutes !)
1/ Créer une fenêtre (JFrame) …. dans une classe (= plus exactement un objet issu d’une…) GUI dans un package « vue ».
2/ Dessiner son interface (logiciel de mockup). Choisir une taille originale (de base) pour votre jeu même si on choisit un type d’interface qui accepte le redimensionnement (exemple : 800x600 ou 1280x720).
3/ Utiliser un gestionnaire de placement (Layout) : ici SpringLayout qui permet le redimensionnement.
4/ Implémenter/positionner les éléments d’interface sans se soucier des actions.
NB : On commence simple « sans fioritures » mais avec tous les éléments nécessaires.
Important : Il vaut mieux repartir de zéro si on veut ensuite « améliorer » son interface avec l’ajout de nouveaux composants ou en remplaçant certains par d’autres (exemple : liste déroulante remplacée par un « slider ») sinon on se retrouve généralement avec une interface qui « sent » le bricolage…
Description détaillée ci-après :
Jour 1 détaillé : Etape 1 :
On crée un nouveau projet D&D_CampusChy
On crée un package Warriors et dedans 3 sous-packages Modèle, Vue, Contrôleur (MVC).
Une nouvelle classe GUI dans le package vue et toujours la classe Main avec la méthode main() à la racine du projet (=dans warriors).
(Pause : explication par le formateur de MVC, des « intégristes » et de ceux qui prennent un peu de recul par rapport au « dogme » pour faciliter/simplifier l’écriture ou la lecture du code). Beaucoup de débats à ce sujet pour les forums web…).
TIPS : La structure d’un projet JAVA doit être claire dans votre tête. MVC est une surcouche facultative (=on peut faire sans) qui peut vous aider ou vous perdre suivant votre niveau d’expérience, de compréhension ou de maitrise…
Etape 2 :
Dans la classe GUI, on va créer une fenêtre (objet de type JFrame issu de la bibliothèque graphique « Swing »). Elle se trouve dans javax.swing.JFrame donc on importe la classe en question.
Notre classe GUI va donc être une sorte de JFrame : on utilise le principe de l’héritage.
(extends JFrame).
Dans le constructeur, on va juste commencer par lui donner car informations basiques pour pouvoir l’afficher :
Taille, titre, position sur l’écran, configurer ce qui se passe quand on la ferme.
Puis on l’affiche…à la fin du constructeur quand tout est prêt !
NB : On teste très régulièrement car sinon les problèmes sont plus difficiles à trouver…
Une fois ceci fait, dans main() de la Classe Main, on instancie donc juste une new GUI() et on vérifie que tout marche bien… bon, qu’une fenêtre s’affiche quoi !
Etape 3 :
On va réfléchir à notre « interface utilisateur graphique » : on pourra être créatifs plus tard lorsque vous maitriserez et aurez bien compris le principe mais pour commencer, on va rester classique.
On va donc ajouter une barre de menus à notre fenêtre. En Swing, ce widget s’appelle…..
JMenuBar ! Oui, pourquoi pas ?
Je vous explique le principe : une menuBar sera composée de Menu(s) qui eux-mêmes seront composé de MenuItem (comme on utilise Swing : tout commencera par J : JMenu, JMenuItem…).
Bon, c’est plus clair avec une image ?
Je vous laisse deviner ou comprendre ce qui est la JMenuBar, les 3 JMenu et les 3 JMenuItem du JMenu Jeu qui est déroulé….
(ah mince j’ai donné une partie de la réponse ).
Alors là, on va faire un peu de méthodologie :
1/ vous réfléchissez et imaginez votre barre de menu. Eventuellement, vous la dessinez sur papier.
2/ on liste les différents éléments avec des noms explicites (éviter menu1 car c’est plus pratique de recherche menuJeu ou menu1jeu si vous voulez sa position dans l’affichage) et on les associe. Pareil pour les items, pour savoir à quel menu, ils appartiennent…
3/ on les crée dans le code.
Bon, comme il faut que vous appreniez à lire du code, je vous ai trouvé un exemple à peu près compréhensible (dans build() ):
https://baptiste-wicht.developpez.com/tutoriels/java/swing/debutant/?page=menus
Une petite aide pour la construction : pour les items, ils vont déclencher des actions…donc l’instanciation est un peu spéciale mais je propose qu’on le fasse plus tard car pour
l’instant, on construit juste l’interface sur le plan visuel.
Donc pour les JMenuItem, vous les déclarez juste avec une chaîne de caractères : private JMenuItem creer= new JMenuItem("Créer votre personnage");
Ils afficheront le texte mais ne feront rien quand on clique dessus.
On verra plus tard mais notez que le site concerné montre la/une solution.
Attention, il y a un ordre : on crée les éléments puis on ajoute les plus petits (item) dans leur conteneur (menu) et enfin on ajoute les menus à la barre.
Et quand tout cela est prêt, on n’oublie pas d’attacher la barre à la fenêtre :
this.setJMenuBar(menuBar);
Tips : erreur classique : le « this.setVisible(true) » doit être à la fin sinon on affiche la fenêtre avant que la barre ne lui soit associée…
Etape 4 :
Pour la barre, ça n’est pas trop compliqué car sa position par défaut est toujours en haut à gauche mais pour les autres composants (widgets), on doit absolument décider de leur répartition/plan dans la fenêtre.
Pour cela, on va utiliser un layout et comme on est fort, on va en prendre un bien puissant : le SpringLayout qui utilise des principes de programmation par contrainte avec des
ressorts. Le truc vraiment cool, c’est qu’on peut redimensionner la fenêtre et il tente d’adapter en respectant les contraintes… Bon, après y a pas de miracle, sur une fenêtre de largeur de 10 pixels, l’interface va pas être nickel, nickel…
Sur le plan de la méthode, on va là aussi, éviter de se lancer comme des bourrins dans le code et commencer par faire un « mockup » avec logiciel gratuit à disposition (ex : mockingbird) ou sur une feuille, papier,crayon, comme vous voulez…
https://korben.info/18-outils-gratuits-mockups.html
https://www.blogduwebdesign.com/logiciels-wireframe-prototype/
https://graphiste.com/blog/outils-creer-wireframes-mockups
1/ Vous faites donc la maquette de votre interface…
2/ Vous identifiez/listez les widgets donc vous avez besoin : bouton, panel, texte, champs de saisie, image, etc.
Voilà un exemple pour un autre projet, bien sûr :
3/ Vous repérez les contraintes entre les éléments (en termes de pixels).
4/ On se lance dans le codage.
a/ on déclare les variables et objets dont on va avoir besoin (avec des noms explicites…)
b/ on instancie un springLayout.
Attention l’exemple ci-dessous était pour une applet java (un programme qui tourne dans un navigateur) alors que nous faisons actuellement une application sous forme de JFrame mais c’est similaire.
NB : Pour dessiner le plateau/aire de jeu, on va juste réserver pour l’instant un composant de type JPanel.
c/ on positionne les éléments les uns par rapport aux autres en déclarant les contraintes.
cf. code sur la seconde image ci-dessus.
Exemple : « Le bouton X est bloqué à 50pixels du bord gauche et 100 pixels du bas de la fenêtre. »
« La taille de cet élément est bloqué en hauteur à 150 pixels »
Tips : Attention, bloquer un élément en taille permet de s’assurer d’avoir exactement l’affichage prévu mais sera ensuite moins flexible lorsqu’on étirera ou réduira la fenêtre. Mon conseil : ceux qui trouve cela compliqué : partez sur du fixe et tant pis, le jeu ne sera pas (ou pas trop « responsive »). Pour les autres, il suffit de 2 contraintes (1 latérale et 1 horizontale pour positionner un élément), ensuite le springLayout adapte sa taille… Comme d’habitude, allez-y par étape, petit à petit, car si vous rentrez tout d’un coup et qu’une contrainte est incohérente : le système ne s’affichera pas et bonne chance pour trouver l’erreur !
d/ Quand c’est ok, on attaque le plateau (JPanel) : l’idée est de créer un classe spécifique qui hérite de JPanel ce qui facilitera le rafraichissement pour la mise à jour du plateau où on devra redessiner les éléments à la bonne position.
Dans le constructeur, on charge les images nécessaires. Pour les dalles, j’ai choisi de les dessiner sous forme de rectangle avec les méthodes fournies par JAVA.
On affichera aussi les images pour les éléments liés au joueur ou aux événements aléatoires.
Si vous êtes allé vite :
Aide pour le code pour afficher des images et dessiner un carré dans le JPanel:
Vous posez les images dans un dossier séparé (cf. image ci-dessous). Les images se chargent ensuite dans le constructeur pour pouvoir les manipuler et les afficher dans une méthode paint() de la classe Panneau qui hérite de JPanel.
Code : pour charger les images :
//déclaration
// déclaration de l’image
Image fondImg, magoImg, warriorImg, joueurImg;
// adresse de l’image
String imgFondAdresse="images/fond.jpg";
String imgMagoAdresse="images/imageMagicien.png";
String imgWarriorAdresse="images/imageGuerrier.png";
// dans le constructeur //on charge les images try {
//on récupère l'image à l'adresse où on l’a mise…
fondImg=Toolkit.getDefaultToolkit().getImage((imgFondAdresse));
magoImg=Toolkit.getDefaultToolkit().getImage((imgMagoAdresse));
warriorImg=Toolkit.getDefaultToolkit().getImage((imgWarriorAdresse));
//fin chargement des images.
catch (Exception e)
{System.out.println("erreur dans le chargement des images:"+e);};
System.out.println("si pas erreur juste avant chargement des images ok");
Enfin pour dessiner, c’est dans une méthode paint() :
•
les images :public void paint(Graphics g) {
g.drawImage(fondImg, 0, 0, this.getWidth(), this.getHeight(), null);
•
un carré (en position 10,15 et de taille 50,60 avec effet 3D « relief » (true)):// on dessine une case g.setColor(Color.darkGray);
g.fill3DRect(10,15,50,60,true) ;
e/ Attention, là ce n’est que de l’affichage : il reste à faire le lien avec vos classes de la semaine dernière.
On a plusieurs possibilités :
•
soit tout coder les événements pour qu’ils apparaissent sur le plateau…•
soit s’appuyer sur des fenêtres d’interaction JAVA en réaction aux boutons et annoncer à l’utilisateur, l’événement qui se produit…Pour commencer, il parait plus simple de démarrer avec la seconde solution : l’appui sur avancer produira un lancer de dés et donnera le résultat dans une fenêtre de dialogue. On pourra aussi rendre « disable » les boutons qui ne sont pas activables à un moment du jeu.
Livrable à la fin de la journée :
Un code JAVA qui lance une fenêtre avec une interface pour le jeu (barre de menu, boutons et un JPanel central qui représente le plateau de jeu (si possible avec une image de fond et un ou plusieurs carrés qui représentent les cases du jeu).