Travaux Dirigés DUT SRC 2 Didier Arquès Partie II. Sujet Programmation Orientée Objet – TP Swing Résumé Objectif final : Maîtriser la réalisation d’interfaces avec Java et Swing. Connaissances requises : • le cours Java sur Swing • pour une version plus élaborée (jeu de tetris par exemple), la notion de thread Objectifs intermédiaires : TD n°7 : Concevoir l’aspect d’un IHM Contenu : Utiliser les conteneurs, les composants et les gestionnaires de disposition. Plusieurs exemples simples seront traités et associés in fine pour obtenir la disposition voulue sur le plateau de jeu. Conteneurs : JFrame, JPanelGestionnaires de disposition utilisés : FlowLayout (présentation en file)GridLayout (présentation en grille) BorderLayout (présentation avec bordures)GridBagLayout (présentation en grille composite)Composants utilisés : JButton, JLabelObjets graphiques : créer un panneau de dessin et dessinerimporter une image TD n°8 : Ecouter et gérer les événements Contenu : Implémenter l’interface auditeur. Objets graphiques et événements Gérer plusieurs événements, notion de classe interne On dessinera des objets sur le plateau central de l’IHM. On associe des changements d’état (couleur par exemple) aux boutons. On utilisera des fonctions mathématiques comme Math.random() TD n°9 : Animation Contenu : classe interne, gestion des événements et animation des graphiques. Concernant le jeu de poursuite de cible, • définir une stratégie d’évitement pour la cible, • mettre en place la gestion de la vitesse de la cible au travers de boutons, • mettre en place la gestion du déplacement du missile guidée par boutons TD n°10 : Installer un plugin Java sous Eclipse TD n°11 : Créer une interface avec Visual Editor TD n°12 : Etudier d'autres types de listener Contenu : • dessin avec la souris • reprise du jeu de poursuite en guidant le missile avec les flèches du clavier p. 4 TD n°7 : Concevoir l’aspect d’un IHM Contenu : Utiliser les conteneurs, les composants et les gestionnaires de disposition. Plusieurs exemples simples seront traités et associés in fine pour obtenir la disposition voulue sur le plateau de jeu. Gestionnaires de disposition utilisés : FlowLayout (présentation en file)GridLayout (présentation en grille) BorderLayout (présentation avec bordures)GridBagLayout (présentation en grille composite)Composants utilisés : JButton, JLabelObjets graphiques : créer un panneau de dessin et dessinerimporter une image Exercice 1 : Un premier IHM Durée 2H 1) Quelle est la fenêtre racine d’un IHM ? Quel est le conteneur racine associé à cette fenêtre ? Quel est le gestionnaire d’agencement (layout manager) par défaut associé à ce conteneur ? Rappeler par un dessin comment ce gestionnaire dispose les composants. 2) Créer une telle fenêtre racine que l’on appellera cadreglobal objet JFrame Comment ferme-t-on « proprement » une fenêtre ? 3) Rappeler ce que vous savez de la classe JPanel. 4) Compléter cadreglobal en mettant à l’est un panneau « boiteBoutonsDéplacements » (instance de JPanel), au sud un panneau « boiteBoutonsJeu » et au centre un panneau « panneauDessin ». Que constatez-vous si vous affichez l’interface ? Colorer ces panneaux en vert à l’estet en rouge au sud, grâce à la méthode setBackground(Color.green) 5) Quelle est la classe SWING du composant bouton ? Quel est le gestionnaire d’agencement par défaut d’un objet JPanel ? Ajouter au panneau « boiteBoutonsDéplacements » 4 boutons (pour les déplacements dans les quatre directions (àDroite, àGauche, enHaut, enBas). Ajouter au panneau « boiteBoutonsJeu », 2 boutons « Accélérer », « Ralentir ». 6) Quelle est la classe SWING du composant étiquette ? d’une zone de saisie de texte ? Ajouter au panneau « panneauDessin » le texte : « ceci sera ma zone de dessin » En attendant de savoir dessiner…ajouter ensuite une zone de saisie de texte de 10 lignes et 20 colonnes. Modifier la forme de la fenêtre que constate-t-on ? en particulier dans le panneau central ? Pourquoi ? 7) Modifier le gestionnaire d’agencement du panneau "est" de façon à regrouper les 4 boutons 2 par 2 sur 2 lignes. Quel gestionnaire faut-il choisir ? Quels inconvénients apparaissent ? Quel autre gestionnaire choisir pour une meilleure disposition ? Comparer les résultats. Faites des essais pour l’améliorer. 8) Dessiner l’arborescence des composants graphiques de cet interface p. 5 Exercice 2 : Dessiner On reprend le programme java obtenu à l’issue de l’exercice précédent. On souhaite dessiner dans la zone centrale « panneauDessin » au lieu d’écrire comme dans l’exercice 1. 1) Comment crée-t-on un panneau pour dessiner ? Modifiez le programme pour pouvoir dessiner dans panneauDessin. 2) Aller voir la doc sur la classe Graphics. En déduire vos propres dessins. Par exemple, vous dessinerez un rectangle vert et un disque rouge à une place que vous choisirez. Réalisez d’autres dessins. 3) Insérez dans ZoneDessin une image issue d’un fichier. Pour cela, regardez la doc sur la méthode drawImage(…) et sur la classe ImageIcon qui étend Image. Durée 1H Image img = new ImageIcon("nom_fichier_image").getImage(); g.drawImage(img, x, int y, width, height, this); TD n°8 : Ecouter et gérer les événements Contenu : Implémenter l’interface auditeur. Objets graphiques et événements Gérer plusieurs événements, notion de classe interne On dessinera des objets sur le plateau central de l’IHM. On associe des changements d’état (couleur par exemple) aux boutons. On utilisera des fonctions mathématiques comme Math.random(). Exercice 3 : Introduction à la gestion des événements Durée 1H 1) Rappelez le cours sur l’écoute et la gestion des événements. 2) Prendre l’exemple suivant et le modifier pour prendre en compte les quatre étapes principales de la gestion de l’événement lié au clic sur le bouton qui devra faire apparaître un nouveau texte sur le bouton : « j’ai été cliqué ». package tp2_exercice4; import javax.swing.*; class SimpleIHM extends JFrame { private JButton bouton; public SimpleIHM () { this.setTitle("GestionBouton"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(300,300); créerIHM(); } public void créerIHM() { bouton = new JButton("cliquez moi"); this.getContentPane().add(bouton); } } public class TestSimpleIHM { public static void main (String[] args) { JFrame ihm = new SimpleIHM() ; ihm.setVisible(true); } } 3) Vous avez déjà rencontré une gestion d’événement au TP précédent : laquelle ? p. 6 Exercice 4 : Gestion de plusieurs événements L’objectif de cet exercice est de voir comment gérer plusieurs sources d’événements dans le même IHM 1) Implanter l’IHM très simple suivant constitué de deux boutons l’un à l’est, l’autre au sud, et d’une étiquette au centre. Durée 1H 2) Implanter une action associée à chaque bouton : Chacun des boutons, lorsqu’il est cliqué change le texte de l’étiquette située au centre : l’un écrit « je fais la… » l’autre écrit « …java ». On proposera deux méthodes : • la première impose aux deux boutons de partager la même méthode : actionPerformed(ActionEvent event) qui doit tester quel est le bouton qui l’appelle grâce à l’événement event passé en paramètre (aller voir dans la doc la méthode getSource()). • La seconde associe à chaque bouton une classe qui implémente ActionListener, classe interne à la classe de l’IHM. Chacune de ces deux classes a juste à implémenter sa prope méthode actionPerformed. 3) Discuter de l’intérêt relatif des deux méthodes. Exercice 5 : Gestion de plusieurs événements A faire en temps libre Reprendre l’exercice précédent, l’un des boutons gérant du texte situé à l’est et l’autre gérant un panneau de dessin situé au centre. Un clic sur ce bouton doit changer aléatoirement la couleur du rectangle (par exemple) dessiné. On implantera les deux méthodes de gestion des événements. On appliquera l’implantation d’une zone de dessin vue à l’exercice 2. Pour définir une couleur au hasard, on utilisera (après l’avoir expliquée) la méthode : public Color couleur(){ int red=(int) (Math.random()*255); int green=(int) (Math.random()*255); int blue=(int) (Math.random()*255); return(new Color(red,green,blue)); } p. 7 Exercice 6 : Gestion du déplacement d’un objet avec les boutons Durée 1H On reprend le programme Java de l’exercice 2 en ne dessinant qu’un carré (de coin en haut à gauche (x,y) et de taille « taille=20 ») sur le plateau de dessin. Le but est de déplacer ce carré à l’aide des boutons de déplacement placés sur le panneau EST. Cliquer sur l’un des boutons de ce panneau EST doit conduire au décalage du carré vert dans la direction du bouton d’un nombre de pixels égal à « décalage ». 1) On créera ces deux variables taille et décalage. La variable « décalage », initialisée à 10 fixe la « vitesse » de déplacement du bouton sous l'action des boutons de déplacement (panneau au SUD « Accélérer » et « Ralentir »). On peut modifier la vitesse en augmentant ou diminuant décalage. 2) Gérer l’encapsulation des variables d’instances (méthodes set que l’on peut installer automatiquement dans Eclipse) afin de vérifier la validité des affectations (il faut vérifier que le carré vert ne sort pas du plateau de jeu) Indication : Créer les méthodes setX, setY et setDécalage qui permettent d'affecter des valeurs aux propriétés x, y, décalage tout en contrôlant cette valeur (il faut que le rectangle vert reste sur le plateau !, que sa vitesse reste positive !) public boolean setX(int x) {//méthodes set d'affectation if((x>=10)&&((x+taille)<panneauDessin.getWidth())){this.x = x;return true;} else return false; } public boolean setY(int y) {//méthodes set d'affectation if((y>=45)&&((y+taille)<panneauDessin.getHeight()+30)){this.y = y;return true;} else return false; // la méthode suivante fixe la vitesse de déplacement public boolean setDécalage(int décalage) { if((2<=décalage) && (décalage<=50)) {this.décalage = décalage; return true;} else return false; } 3) Implanter la gestion du déplacement du carré vert (à droite, à gauche, vers le haut, vers le bas) dans les directions correspondant aux quatre boutons. Indication : Pour le bouton Agauche, par exemple, on fixe la nouvelle position (décalage en x) et on appelle si ce décalage est possible (on est toujours sur le plateau) la méthode repaint() : public void actionPerformed(java.awt.event.ActionEvent e) { if (setX(x-décalage)) {panneauDessin.repaint();} } Deux aspects sont à prendre en compte : ne pas sortir du plateau et appeler la méthode repaint() dans chaque méthode actionPerformed() appelée, de façon à provoquer la mise à jour du dessin. 4) Implanter la gestion de la vitesse du carré vert en définissant les méthodes actionPerformed associées aux listeners des deux boutons « Accéléreré et « Ralentir » p. 8 TD n°9 : Animation Durée 2H Contenu : classe interne et animation des dessins. Exercice 7 : Une animation simple Durée 1H30 On réalise un programme java qui dessine un disque en mouvement. 1) Créer une fenêtre uniquement remplie par un panneau pour dessiner. La classe fenêtre contient une méthode créerIHM qui ajoute un panneauDessin, objet de la classe interne ZoneDessin qui étend JPanel et redéfinit la méthode paintComponent (voir TP1 exercice 2). Cette méthode dessine un disque de couleur et position à choisir (x,y) et de taille (largeur, hauteur) à définir. 2) Modifier la méthode créerIHM de façon à modifier continûment la position (x,y) du disque dessiné sur le panneauDessin selon une trajectoire à choisir. On appellera la méthode repaint() à chaque changement de (x,y). problème ? 3) Vous devez constater quelques problèmes dans l’affichage. Lesquels ? Indication : si le dessin est trop rapide, vous pouvez ralentir l’exécution en « endormant quelques millisecondes le Thread principal : Thread.sleep(50); … attention à la gestion des exceptions C’est la première fois que l’on rencontre la notion de Thread. p. 9 TD n°10 : Installer un plug-in sous Eclipse Durée 2H Exercice 8 : Objectifs : Installer un plugin Java sous Eclipse. On présuppose une version de base d'éclipse est installée. On se propose d'installer Visual Editor sous Eclipse. Suivre les différentes étapes du corrigé : 1) Télécharger sur le site d'éclipse « http://www.eclipse.org/downloads/index_project.php » 3 éléments : VE « visual editor » qui nécessite les 2 plug-ins supplémentaires : EMF et GEF. 2) Télécharger ces 3 plug-ins dans un dossier (par exemple « Visual Editor ») qui contient donc 3 sous-dossiers : « emf… », « GEF… » et « VE… ». Vous constaterez que ces 3 dossiers téléchargés contiennent tous un sousdossier nommé « eclipse ». 3) Les étapes suivantes changent selon la version d’Eclipse ! (ici v.3.3.2) Adaptez-les pour les versions ultérieures. Installer chacun de ces 3 plug-ins en suivant les étapes suivantes (on pourrait également installer ces plug-ins directement à partir du site The Eclipse Project Updates sans passer par une recopie locale). i. Help > Sftware Updates > Find and Install… La fenêtre “Install/Update” s’ouvre ii. Cocher la case “Search for new features to install” et cliquez sur la case “Next” iii. Dans la fenêtre “Install”, cliquez sur le bouton « New Local Site » la fenêtre « Rechercher un dossier » s’ouvre. Sélectionnez le sous-dossier « eclipse » du dossier « VE… » et cliquez sur le bouton OK iv. Une fenêtre de confirmation « Edit Local Site » s’ouvre … cliquez sur le bouton OK. Dans la fenêtre « Install », un nouveau site est apparu (sa case est cochée) : « VE… » dans la liste des sites. v. Recommencez les étapes iii) et iv) avec le sous-dossier GEF et le sous-dossier EMF. vi. A la fin, 3 sites sont sélectionnés dans le fenêtre « Install » voir image ci-contre : Cliquez que le bouton « Finish » de la fenêtre « Install ». Une fenêtre « Updates » rassemblant les 3 sites apparaît. Cliquez sur le bouton « Next ». Acceptez la licence et cliquez sur « Next ». Laissez le dossier d'installation par défaut… et cliquez sur Finish… L'installation des plug-ins se fait alors automatiquement. Un constructeur d'IHM comme VE est pratique pour les débutants en conception graphique Java, car il permet en quelques clics de tester les différentes possibilités de chaque composant sans avoir besoin de connaître le code qui correspond. Mais comme la construction d'une interface graphique s'effectue de façon programmatique en Java, un programmeur expérimenté préfèrera coder à la main cette construction en utilisant son style de programmation, plutôt que de se laisser imposer le style de code de l'éditeur graphique (surtout que certains IDE ne permettent même pas de retoucher le code Java généré par l'outil graphique). Vous comparerez dans la suite votre propre code à celui généré par VE. TD n°11 : Créer une interface avec Visual Editor Durée 2H Exercice 9 : Maquette Swing : Créer une interface avec Visual Editor. L'objectif est d'utiliser Visual Editor pour réaliser cet interface de jeu où les boutons à droite permettent le déplacement de la cible verte dans les directions et les boutons au sud arrêtent le jeu ou augmentent ou diminuent le déplacement de la cible verte. Il s'agit donc également de gérer les actions des boutons présents dans cet interface. Ce type d'exercice a déjà été programmé en TD (voir polycopié des TD précédents). On comparera les styles de programmation. 1) L'éditeur VE est directement associé à la création de classes graphiques, sous différents intitulés qui se terminent par Visual Class. p. 10 Créer avec VE une classe de type fenêtre Swing : 0) Choisir le menu File>New>JavaProject et créer un nouveau projet TestVE 1) Choisir le menu File>New>Other. 2) Sélectionner l'élément : Java>Swing>JFrame Visual Class dans l'arborescence des Wizards affichés. 3) Saisir le nom de la classe (IHM_1) et de son package (swingTest) puis choisir le style de fenêtre à créer : Frame pour une simple sous-classe de JFrame ou Application pour une classe plus complète avec des menus par défaut. Choisir dans cet exemple Frame (vous choisirez Application dans un exemple à venir). Une fois cette classe créée, Eclipse lance automatiquement VE et active la vue Java Beans qui permet d'explorer l'arborescence des composants qui dépendent de la fenêtre. La zone d'édition de la classe IHM_1 est divisée en 3 parties : • Un éditeur graphique montrant l'aspect de la fenêtre avec ses composants et ses menus • une palette énumérant tous les composants graphiques qu'il est possible d'intégrer à la fenêtre • un éditeur de texte où s'affiche le code de la classe généré par VE. Editeur Palette de composan Editeur de texte Vue Java Beans des composants de la fenêtre 2) Commentez ce code qui ouvre une fenêtre et que vous trouvez dans l'éditeur de texte. Quelles sont les différences avec votre style de programmation ? Commentez en particulier l'ajout explicite d'un JPanel à la fenêtre. 3) Ajout des composants : Pour ajouter un composant, on le sélectionne dans la palette, puis on clique dans la zone adéquate de l'éditeur graphique. A chaque ajout, VE propose de choisir le nom du champ associé au nouveau composant. Suivez les étapes et devinez celles qui manquent en fouillant un peu VE! pour reconstruire la partie sud de l'interface (constitué d’un JPanel et de 3 boutons) du jeu de déplacement d’un objet ci-contre. Examinez le code produit et commentez le. Remarquez que vous pouvez dynamiquement modifier ce code et voir le résultat sur l'interface. p. 11 4) Propriétés d'un composant : Certaines propriétés sont accessibles avec le clic droit de la souris après avoir sélectionné l'élément concerné dans JavaBeans ou dans la fenêtre représentant l'interface. Une autre méthode plus complète consiste à ouvrir la fenêtre Properties : elle propose toutes les propriétés de l'élément sélectionné dans JavaBeans. Ouvrez cette fenêtre Properties et testez les modifications que vous pouvez faire… par exemple enchangeant le nom des boutons. Pousuivre la construction de l'interface à l'est : Créer à présent à l'est un JPanel boiteBoutonsDeplacement muni d'un ordonnancement « gridBagLayout » En utilisant les propriétés, vous pouvez : • choisir (c'est par défaut) le mode gridBagLayout • donner une taille préférée (sinon le JPanel apparaît initialement de largeur nulle) • modifier la couleur du background (on l'a mis en rose) • … Ajoutez à présent les boutons : En chosissant JButton dans la palette, en glissant la souris vers le JPanel rose, lorsque vous cliquez sur le JPanel, un bouton est positionné automatiquement en position (0,0) d'une grille automatiquement dessinée. Attention à mettre une bonne taille à la fenêtre globale (dans la méthode resize() ). 5) Ajouter une icône : Sélectionnez par exemple le bouton Agauche. Dans ses propriétés, il s'agit du champ icon (cliquez dessus puis sur les … qui appararaissent à droite). Une fenêtre s'ouvre. Allez chercher dans votre système de fichier (cochez la case « File system ») le dossier contenant vos images et choisissez celle à associer au bouton AGauche (par exemple). Vous pouvez également renseigner le champ « rollovericon » des propriétés qui permet de mettre une seconde image qui remplace la première lorsque la souris passe sur le bouton (pour constater le résultat, il faut compiler effectivement le code java. L'effet n'apparaît pas dans l'éditeur graphique de VE). In fine, vous obtenez l'interface de l'image ci-contre. Examinez le code et déterminez les modifications faites sur les propriétés dans ce code. 6) Dessiner : Ajouter un JPanel au centre, appelé « panneauDessin » avec les propriétés suivantes : • Son fond est blanc • Son bord est entouré d'une ligne et à pour titre « plateau du Jeu » Ce JPanel va nous servir pour dessiner et jouer. Dessiner un carré vert sur ce panneau, carré dont le bord en haut à gauche a pour coordonnées (x=100, y=100) et de côté (taille =) 20. A cette fin, surcharger la méthode paint() héritée de la classe Container. Elle est appelée automatiquement lors de la création de l'interface : java.lang.Object java.awt.Component java.awt.Container java.awt.Window java.awt.Frame javax.swing.JFrame p. 12 public void paint(Graphics g) Paints the container. This forwards the paint to any lightweight components that are children of this container. If this method is reimplemented, super.paint(g) should be called so that lightweight components are properly rendered. If a child component is entirely clipped by the current clipping setting in g, paint() will not be forwarded to that child. Overrides: paint in class Component public void paint(Graphics g) { super.paint(g); g.setColor(Color.green); g.fillRect(x,y,taille,taille); } 7) Le jeu consiste à faire évoluer ce carré vert par les flèches (à l'est) indiquant les 4 directions et avec une vitesse gérée par les deux boutons au sud (Accélérer et Ralentir). Gérer l'action des 7 boutons en vous aidant de vos connaissances acquises dans les exercices précédents. Pour gérer l'action d'un bouton, il suffit de le sélectionner (dans la fenêtre Java Beans ou dans la fenêtre graphique), puis de cliquez dessus avec le clic droit de la souris, de sélectionner le menu Events>actionPerformed : VE ajoute alors automatiquement l'ActionListener et la méthode actionPerformed() associée au bouton. Cette méthode ne fait rien d'autre à ce stade qu'une édition (lorsqu'on exécute le programme). Elle reste à implanter. Il faut compléter le code obtenu en : • Créant une variable « décalage », initialisée à 10 et qui fixe la « vitesse » de déplacement du bouton sous l'action des boutons de déplacement. On peut modifier la vitesse en augmentant ou diminuant décalage. • Créant les méthodes (par le clic droit de la souris) setX, setY et setDécalage qui permettent d'affecter des valeurs aux propriétés x, y, décalage tout en contrôlant cette valeur (il faut que le rectangle vert reste sur le plateau !, que sa vitesse reste positive !) public boolean setX(int x) {//méthodes set d'affectation if((x>=10)&&((x+taille)<panneauDessin.getWidth())){this.x = x;return true;} else return false; } public boolean setY(int y) {//méthodes set d'affectation if((y>=45)&&((y+taille)<panneauDessin.getHeight()+30)){this.y = y;return true;} else return false; } // la méthode suivante fixe la vitesse de déplacement public boolean setDécalage(int décalage) { if((2<=décalage) && (décalage<=50)) {this.décalage = décalage; return true;} else return false; } • Achevant la méthode actionPerformed() gérant l'action du bouton considéré : pour le bouton Agauche, on fixe la nouvelle position (décalage en x) et on appelle si ce décalage est possible (on est toujours sur le plateau) la méthode repaint() : public void actionPerformed(java.awt.event.ActionEvent e) { if (setX(x-décalage)) {repaint();} } p. 13 TD n°12 : Etudier d'autres types de listener Durée 2H Contenu : • dessin avec la souris • reprise du jeu de poursuite en guidant le missile avec les flèches du clavier Exercice 10 : Dessiner avec la souris Durée 1H30 On réalise un programme java qui dessine avec la souris. Le but est de créer un panneau sur lequel le déplacement de la souris provoque le dessin de points, ce qui permet de tracer des courbes 1) Créer une fenêtre uniquement remplie par un panneau pour dessiner (voir exercice 7). La classe fenêtre contient une méthode créerIHM qui ajoute un panneauDessin, objet de type JPanel Indication : Ici on n'étend pas JPanel par une classe ZoneDessin qui redéfinit la méthode paintComponent. On pratiquera en effet autrement en utilisant des méthodes de JPanel (héritées de JComponent) qui permettent de récupérer l'objet Graphics qui permet de dessiner sur le panneau. 2) Gestion des événements liés au déplacement de la souris sur le panneauDessin : • Quel est le composant source de l'événement "dessiner avec le déplacement de la souris"? • Quelle est la méthode « add...Listener» dans la classe (ou une surclasse) de ce composant source qui permet de gérer la souris ? • Choisir la méthode qui nous intéresse et que nous devons redéfinir de l'interface MouseMotionListener (cet interface déclare deux méthodes : lesquelles?) 3) Implanter une classe interne : class DessinListener implements MouseMotionListener et redéfinir la méthode qui nous importe dans l'interface. Indication : – l'événement e généré par le déplacement souris est capable d'indiquer l'objet dont il est issu grâce à la méthode getSource() : Expliquer et utiliser le code suivant Graphics g = ((JComponent)e.getSource()).getGraphics(); – – Chercher les méthodes qui permettent de récupérer les coordonnées de la souris? Déduire de ces deux indications le code de la méthode public void mouseMoved(MouseEvent e) Que doit-on faire de la seconde méthode de l'interface? p. 14 Exercice 11 : Dessiner avec la souris…suite Durée 1H30 On reprend le programme Java de l'exercice 10. On souhaite ajouter une barre d'état qui affiche les coordonnées de la souris à tout instant selon la figure: 1) 2) 3) Créer une étiquette "etiquetteBarreEtat" dans la partie sud de la fenêtre contenant en son centre Gérer les événements liés au déplacement de la souris sur le panneauDessin en indiquant au panneauDessin que l'on est à l'écoute des déplacements de la souris : Comme à l'exercice 10, on passera en argument un objet d'une classe interne (voir question suivante) qui implémente MouseMotionListener. Implanter une classe interne : class MajCoordonnéesListener implements MouseMotionListener { 4) et redéfinir la méthode mouseMoved de l'interface pour qu'elle affiche les coordonnées (voir figure) dans l'étiquette etiquetteBarreEtat. Dessiner l'organigramme des classes de cette application (sans en oublier). p. 15