FAQ Java GUIConsultez toutes les FAQ
Nombre d'auteurs : 37, nombre de questions : 155, dernière mise à jour : 10 octobre 2015 Ajouter une question
Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums de http://www.developpez.com et de l'expérience personnelle des auteurs.
Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.
- Que sont les listeners ?
- Comment utiliser les listeners (Méthode 1) ?
- Comment utiliser les listeners (Méthode 2) ?
- Comment utiliser les listeners (Méthode 3) ?
- Qu'est-ce qu'est et comment utiliser ActionListener ?
- Qu'est-ce qu'est et comment utiliser KeyListener ?
- Qu'est-ce qu'est et comment utiliser MouseListener ?
- Qu'est-ce qu'est et comment utiliser WindowListener ?
- Qu'est-ce qu'est et comment utiliser FocusListener ?
- Qu'est-ce qu'est et comment utiliser ItemListener
Dans le contexte d'une interface graphique (Swing, AWT, etc.), les listeners permettent au programmeur de réagir suite aux actions de l'utilisateur (clic de souris, touche du clavier enfoncée, etc.).
Les « listeners » sont des interfaces. Ces interfaces fournissent une ou plusieurs méthodes qui peuvent donc être implémentées différemment selon les cas et les besoins, pour répondre aux événements.
Les interfaces « listener » sont présentes principalement dans le package java.awt.event, mais également dans le package javax.swing.event.
Chaque listener dispose d'une classe Event associée. Cette classe étend java.awt.event.EventObject et fournit une description de l'événement capturé. Par exemple, la classe ActionEvent décrit les événements capturés par un ActionListener.
Il y a plusieurs manières d'utiliser les listeners, vous trouverez ces méthodes dans les Q/R suivantes.
Voici la présentation et quelques explications sur la première possibilité concernant l'utilisation des listeners.
1ère possibilité : implémentation de l'interface dans la classe principale.
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import java.awt.event.ActionListener; // Étape 1 : déclaration de la classe public class MaClasse implements ActionListener { // Étape 3 : Création de deux boutons JButton monBouton = new JButton("Mon Bouton"); JButton monBouton2 = new JButton("Mon Bouton2"); public MaClasse() { // Étape 4 : On ajoute « l'écouteur » sur le bouton « monBouton ». monBouton.addActionListener(this); // Puis sur monBouton2 monBouton2.addActionListener(this); } /* Étape 2 :Cette méthode est déclarée dans l'interface ActionListener. Il nous faut l'implémenter. */ public void actionPerformed(ActionEvent e) { // Étape 2bis if(e.getSource() == monBouton) { // Bouton 1 a été cliqué }else { // Bouton 2 a été cliqué } } } |
Le cas de l'interface ActionListener est simple puisqu'elle ne contient qu'une méthode.
Méthode que nous implémentons à l'étape 2 justement.
Nous créons un bouton Swing à l'étape 3.
À l'étape 4, nous ajoutons un « listener » sur les boutons précédemment créés. La méthode addActionListener est définie dans la classe AbstractButton, classe parente de JButton. Cette méthode attend un paramètre de type ActionListener.
La classe MaClasse implémente cette interface, elle peut être justement considérée comme du type ActionListener. Nous pouvons donc fournir l'opérateur 'this' en paramètre, qui représente l'instance en cours de la classe MaClasse.
Concrètement, qu'avons nous fait ? Nous avons demandé aux boutons monBouton et monBouton2 qu'ils nous préviennent lorsqu'un utilisateur les actionne (c'est le rôle du « listener » ActionListener en particulier). Et comment ? En utilisant la méthode actionPerformed, définie dans l'interface ActionListener et surchargée dans la classe MaClasse.
Nous avons deux boutons, mais une seule méthode actionPerformed. Nous devons donc différencier (étape 2bis) la source de l'événement, monBouton ou monBouton2.
La boucle est bouclée.
2ème méthode : utilisation des classes anonymes.
Une deuxième possibilité est d'utiliser les classes anonymes. Voici quelques explications, toujours avec un code pour l'exemple.
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // Étape 1 : déclaration de la classe public class MaClasse { // Étape 2 : création de deux boutons. JButton monBouton = new JButton("Mon Bouton"); JButton monBouton2 = new JButton("Mon Bouton 2"); /* Étape 3 : création de la classe anonyme */ monBouton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // Cette méthode ne sera appelée que pour les événements sur le bouton monBouton. } }); /* On refait la même chose pour le deuxième bouton */ monBouton2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // Cette méthode ne sera appelée que pour les événements sur le bouton monBouton2. } }); } |
Tout d'abord, notre classe MaClasse n'implémente pas l'interface ActionListener. Aucune instance de la classe MaClasse ne pourra donc être utilisée dans la méthode addActionListener.
Nous créons deux boutons à l'étape 2. L'étape 3 est la plus intéressante. Nous définissons une instance de l'interface ActionListener dans une classe anonyme, sans garder de référence vers cette classe anonyme. Dans ce cas, nous devons le faire deux fois, une fois pour chaque bouton (il faut une classe anonyme pour chaque composant déclenchant un événement).
Un avantage de cette méthode est un code plus léger au niveau de l'implémentation des événements. En effet, nous n'avons pas à dissocier les composants « source » (les composants écoutés par le listener), comme nous le faisons dans la première possibilité.
En contrepartie, nous devons créer une classe anonyme à chaque fois. Une autre possibilité qui est une simple variante de celle présentée ici est la suivante :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // Étape 1 : déclaration de la classe public class MaClasse { // Étape 2 : création de deux boutons. JButton monBouton = new JButton("Mon Bouton..."); JButton monBouton2 = new JButton("Mon Bouton 2..."); /* Étape 3 : création de la classe anonyme */ ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent e) { if(e.getSource() == monBouton) { // Bouton 1 a été cliqué }else { // Bouton 2 a été cliqué } } }; monBouton.addActionListener(listener); monBouton2.addActionListener(listener); } |
3ème méthode : création d'une classe dédiée.
Code java : | Sélectionner tout |
1 2 3 4 5 | // Fichier : MonListener.java public class MonListener implements ActionListener { public void actionPerformed(ActionEvent e) { } } |
Code java : | Sélectionner tout |
monButton.addActionListener(new MonListener());
ActionListener est, comme son nom l'indique, un listener utilisé pour réagir aux actions utilisateurs. Celles-ci sont multiples, la principale étant l'activation d'un bouton (par un clic ou par appui de la touche Entrée lorsque le bouton est sélectionné).
Une seule méthode est déclarée dans cette interface : public void actionPerformed(java.awt.event.ActionEvent e).
La classe ActionEvent étend la classe java.util.EventObject et hérite donc de ses méthodes. Parmi elles, getSource() est particulièrement intéressante. Elle renvoie l'objet concerné par l'événement (par exemple le bouton qui a été cliqué).
Cela nous permettra de différencier les composants sources dans l'implémentation de la méthode actionPerformed.
La classe ActionEvent fournit quant à elle quelques méthodes spécifiques aux événements d'action. Les plus utilisées sont getWhen() et getActionCommand().
getWhen() récupère le timestamp Unix marquant le déclenchement de l'événement, tandis que getActionCommand() retourne le nom de la commande associée à l'événement (par exemple, le texte du bouton à l'origine de l'action).
Voici une simple implémentation d'un ActionListener, utilisant la première méthode d'implémentation proposée :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | [...] import java.awt.event.*; // Étape 1 : déclaration de la classe public class MaClasse implements ActionListener { // Étape 2 : créations des boutons JButton monBouton = new JButton("Un bouton vivant"); JButton monBouton2 = new JButton("Un bouton vivant2"); public MaClasse() { // Étape 3 : on ajoute le listener aux boutons monBouton.addActionListener(this); monBouton.addActionListener(this); } // Étape 4 : l'implémentation de l'ActionListener public void actionPerformed(ActionEvent e) { System.out.println("Un bouton a été cliqué, timestamp : " + e.getWhen()); // Étape 5 : différenciation de la source d'événement if(e.getSource() == monBouton || e.getActionCommand() == monBouton.getText()) { System.out.println("C'est le bouton 1 !"); }else if(e.getSource() == monBouton2 || e.getActionCommand() == monBouton2.getText()) { System.out.println("C'est le bouton 2 !"); } } } |
Cependant, nous avons deux boutons, et un clic sur chacun d'eux invoquera la même implémentation de l'ActionListener. Nous devons donc différencier le bouton source de l'action. Cela peut se réaliser de deux façons : soit on compare le libellé du bouton avec celui de l'action capturée, soit on compare le bouton et l'objet source de l'événement.
Les deux méthodes sont présentées à l'étape 5. Notez que mettre ces deux tests (comparaison de libellés et comparaison de sources) dans une même condition est superflu, un seul des deux tests est nécessaire pour savoir quel bouton a été actionné.
Le KeyListener est utilisé pour réagir aux événements du clavier, et est donc utilisable sur des composants permettant la saisi de texte (JTextField, JTextArea, etc).
Trois méthodes sont déclarées dans l'interface du KeyListener : keyTyped(KeyEvent e), keyPressed(KeyEvent e) et keyReleased(KeyEvent e). Elle permettent respectivement de réagir lorsqu'une touche a été : tapée (pressée puis relâchée), pressée, relâchée.
La classe KeyEvent étend java.util.EventObject et dispose donc des méthodes déclarées dans cette classe (notamment getSource() ), mais fournit également une dizaine d'autres méthodes spécifiques aux événements relatifs au clavier. Parmi elles : getKeyChar() retourne le caractère associé à la touche appuyée, getKeyCode() récupère le code de la touche pressée, isActionKey() retourne true si la touche appuyée est une touche d'action (CAPS LOCK, Verr Num, etc), et getKeyText(int keyCode) retourne le texte associée à la touche (par ex. F1, A, etc).
La dernière méthode, getKeyText, est statique et ne s'utilise donc pas avec l'instance de KeyEvent fournie.
Les codes retournés par la méthode getKeyCode() sont utiles pour déterminer la touche pressée.
Voici une simple implémentation d'un KeyListener, utilisant la première méthode d'implémentation proposée :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import java.awt.event.*; // Étape 1 : on crée la classe et on implémente KeyListener. public class MaClasse implements KeyListener { // Étape 2 : on crée un composant JTextField private JTextField textField = new JTextField(); public MaClasse() { // Étape 3 : on ajoute le listener au composant textField.addKeyListener(this); } // Étape 4 : on implémente la méthode keyTyped définie dans l'interface KeyListener public void keyTyped(KeyEvent e) { /* Cette méthode est appelée quand l'utilisateur appuie sur une touche Unicode (donc les caractères) et ne prend pas en compte les touches comme F1, Echap, ALT, etc. */ System.out.println(e.getKeyChar()); } // Étape 5: on implémente la méthode keyPressed définie dans l'interface KeyListener public void keyPressed(KeyEvent e) { /* Cette méthode est appelée quand l'utilisateur appuie sur une touche. Il est conseillé de ne pas utiliser getKeyChar() mais getKeyCode(), car les touches spéciales comme F1 ou Echap ne disposent pas d'un équivalent en Unicode, et donc ne peuvent être représentées en char. */ System.out.println(KeyEvent.getKeyText( e.getKeyCode() ); if(e.getKeyCode() == KeyEvent.VK_ESCAPE) { System.out.println("L'utilisateur a appuyé sur Echap"); } } // Étape 6 : on implémente la méthode keyReleased définie dans l'interface KeyListener public void keyReleased(KeyEvent e) { // Le fonctionnement est le même que pour keyPressed, sauf que cette méthode est appelée quand la touche est relâchée. } } |
Enfin, sachez que si vous trouvez trop lourd de devoir implémenter les trois méthodes alors qu'une seule vous suffit, il existe la classe abstraite java.awt.event.KeyAdapter.
Vous pouvez soit créer une classe qui étendra KeyAdapter, soit faire une classe anonyme.
Exemple :
Code java : | Sélectionner tout |
1 2 3 4 5 | monTextField.addKeyListener( new KeyAdapter() { public void keyTyped(KeyEvent e) { } }); |
Le MouseListener est utilisé pour les événements relatifs à la souris (clics, déplacements).
Cinq méthodes sont déclarées dans l'interface MouseListener : mouseClicked(MouseEvent e) prévient des clics (la souris a été pressée puis relâchée), mousePressed(MouseEvent e) pour les pressions sur la souris (donc on enfonce le bouton sans le relâcher), mouseReleased(MouseEvent e) prévient du relâchement d'un bouton de la souris, mouseEntered(MouseEvent e) indique que la souris est entrée dans l'espace d'un composant, mouseExited(MouseEvent e) indique que la souris est sortie de l'espace d'un composant.
La classe MouseEvent étend java.util.EventObject et dispose donc des méthodes déclarées dans cette classe (notamment getSource() ), mais fournit également douze autres méthodes spécifiques aux événements relatifs à la souris, notamment getButton() retourne le bouton qui a été cliqué, getClickCount() retourne le nombre de clics (utile pour gérer le double clic), getLocationOnScreen() retourne un objet Point représentant la position de la souris à l'écran, et enfin isPopupTrigger() précise si le bouton cliqué est celui habituellement utilisé pour afficher la liste déroulante (bouton droit sur le bureau Windows par exemple).
Voici un exemple d'implémentation d'un MouseListener :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | public class MaClasse implements MouseListener { public void mousePressed(MouseEvent e) { // Cette méthode est appelée quand l'utilisateur appuie le bouton sur le composant écouté } public void mouseReleased(MouseEvent e) { // Cette méthode est appelée quand l'utilisateur relâche le bouton sur le composant écouté } public void mouseClicked(MouseEvent e) { // Cette méthode est appelée quand l'utilisateur a cliqué (appuyé puis relâché) sur le composant écouté if(e.getClickCount() == 2) { System.out.println("Il y a eu un double clic"); } Point p = e.getLocationOnScreen(); System.out.println("La souris est aux coordonnées : x=" + p.getX() + ";y=" + p.getY() + " de l'écran."); } public void mouseEntered(MouseEvent e) { // Cette méthode est appelée quand la souris entre dans la zone du composant écouté System.out.println("La souris vient d'entrer..."); } public void mouseExited(MouseEvent e) { // Cette méthode est appelée quand la souris sort de la zone du composant écouté System.out.println("La souris vient de sortir... rattrapez là :)"); } } |
Il existe donc une classe abstraite MouseAdapter qui vous permet d'implémenter seulement les méthodes qui vous intéressent.
Exemple :
Code java : | Sélectionner tout |
1 2 3 4 | monPanel.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { } } |
Le WindowListener est utilisé pour les événements relatifs aux fenêtres (activation, fermeture, ouverture, etc.).
Cette interface déclare sept méthodes : windowActivated(WindowEvent e) indique que la fenêtre a été activée, windowDeactivated(WindowEvent e) indique que la fenêtre n'est plus la fenêtre active, windowClosed(WindowEvent e) indique que la fenêtre a été fermeé, windowClosing(WindowEvent e) indique que l'utilisateur a demandé la fermeture de la fenêtre, windowOpened(WindowEvent e) est appelée la première fois que la fenêtre est rendue visible, windowIconified(WindowEvent e) indique que la fenêtre a été réduite dans la barre de tâche, windowDeiconified(WindowEvent e) indique que la fenêtre a été restaurée depuis la barre de tâche.
La classe WindowEvent étend java.util.EventObject et dispose donc des méthodes déclarées dans cette classe (notamment getSource() ), mais fournit également cinq autres méthodes spécifiques aux événements relatifs aux fenêtres, notamment getNewState() et getOldState() qui fournissent respectivement le nouvel état et l'ancien état de la fenêtre, mais aussi getWindow(), qui retourne la fenêtre source de l'événement.
Afin d'ajouter un WindowListener sur une fenêtre, vous disposez de la méthode addWindowListener(WindowListener) de la classe Window (étendue par la classe JFrame notamment).
Voici un exemple d'implémentation d'un WindowListener :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | public class MaClasse implements WindowListener { // [...] public MaClass() { maFenetre.addWindowListener(this); } public void windowOpened(WindowEvent e) { System.out.println("On vient de m'ouvrir !"); } public void windowClosed(WindowEvent e) { System.out.println("On m'a fermé !") } public void windowClosing(WindowEvent e) { System.out.println("On veut me fermer !"); } public void windowIconified(WindowEvent e) { System.out.println("Je suis réduite à une icône !"); } public void windowDeiconified(WindowEvent e) { System.out.println("Je suis restaurée !"); } public void windowActivated(WindowEvent e) { System.out.println("Je suis activée"); } public void windowDeactivated(WindowEvent e) { System.out.println("Je suis désactivée"); } } |
Le FocusListener est utilisé pour les événements relatifs au focus clavier.
Cette interface déclare deux méthodes : focusGained(FocusEvent e) indique que le composant a gagné le focus clavier tandis que focusLost(FocusEvent e) indique que le composant a perdu le focus clavier.
La classe FocusEvent étend java.util.EventObject et dispose donc des méthodes déclarées dans cette classe (notamment getSource() ), mais fournit également trois autres méthodes spécifiques aux événements relatifs aux fenêtres, notamment isTemporary() qui indique si le composant n'a le focus que temporairement, et getOppositeComponent() qui retourne l'autre composant impliqué dans le changement de focus.
Afin d'ajouter un FocusListener, vous disposez de la méthode addFocusListener(FocusListener) de la classe Component.
Voici un exemple d'implémentation d'un FocusListener :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class MaClasse implements FocusListener { public MaClasse() { monComposant.addFocusListener(this); } public void focusGained(FocusEvent e) { System.out.println("On a gagné le focus"); } public void focusLost(FocusEvent e) { System.out.println("On a perdu le focus"); } } |
Le ItemListener est utilisé pour les évènements relatifs aux éléments (liste, checkbox, etc.).
Cette interface déclare une seule méthode : itemStateChanged(ItemEvent e) qui indique que l'élément a changé d'état.
La classe ItemEvent étend java.util.EventObject et dispose donc des méthodes déclarées dans cette classe (notamment getSource() ), mais fournit également quatre autres méthodes spécifiques aux événements relatifs aux fenêtres, notamment getItem() qui retourne l'élément affecté par l'événement, getStateChange() retourne le nouvel état de l'élément (sélectionné ou désélectionné), et getItemSelectable() qui retourne le composant originaire de l'événement.
Afin d'ajouter un ItemListener sur les composants qui le permettent (les boutons, JcomboxBox, les listes, etc), vous disposez de la méthode addItemListener(ItemListener).
Voici un exemple d'implémentation d'un ItemListener :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class MaFrame extends JFrame implements ItemListener { private JComboBox choix; // [...] public MaFrame() { choix = new JComboBox(); choix.addItemListener(this); } public void itemStateChanged(ItemEvent e) { if(e.getStateChange() == ItemEvent.SELECTED) { System.out.println("Un nouveau choix est sélectionné*: " + e.getItem().toString()); }else if(e.getStateChange() == ItemEvent.DESELECTED) { System.out.println("*Un choix est désélectionné*: " + e.getItem().toString()); } } } |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.