Programmation Java Swing/Gestion des évènements
Un composant peut recevoir divers évènements issus de l'interaction avec l'utilisateur :
- Avec la souris : enfoncement et relâchement d'un bouton, déplacement de la souris, défilement de la molette.
- Avec le clavier : enfoncement et relâchement d'une touche, génération d'un caractère.
- Avec d'autres périphériques d'entrée.
Il peut aussi en générer :
- Un bouton peut notifier le déclenchement d'une action.
- La sélection d'un item dans une liste peut déclencher un évènement.
- ...
Principes de gestion des évènements
modifierDe manière générale, la gestion des évènements en Java se fait de la manière suivante :
- Les classes voulant recevoir une notification d'un évènement enregistrent un écouteur auprès de la source d'évènements. L'écouteur est un objet dont la classe implémente une interface particulière pour traiter un évènement comportant en général une seule méthode appelée pour notifier l'évènement qui s'est produit.
- La source d'évènement (un composant, un périphérique d'entrée : souris ou clavier, ...) notifie les écouteurs enregistrés en appelant la méthode de l'interface particulière. Cette méthode ne comporte en général qu'un seul argument dont la classe dérive de la classe
java.util.EventObject
.
L'exemple ci-dessous illustre comment recevoir un évènement d'action sur un bouton, qui se déclenche au clic avec la souris, ou au clavier quand le bouton a le focus.
JButton b_ok = new JButton("OK");
b_ok.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// ... Action du bouton OK ici
System.out.println("Clic du bouton OK");
}
});
La convention de gestion des évènements est basée sur celle des JavaBeans. Pour un évènement de type type (MouseWheel, Key, Mouse, ...) :
- Une classe d'évènement
typeEvent
dérivant de la classejava.util.EventObject
contient toutes les informations sur l'évènement notifié. - Un écouteur doit implémenter l'interface
typeListener
dont la ou les méthode(s) ont comme seul argument un objet de classetypeEvent
. - La source d'évènement possède deux méthodes publiques :
addtypeListener
pour ajouter un écouteur de l'évènement.removetypeListener
pour retirer un écouteur.
- En général, en interne, la source d'évènement notifie les écouteurs enregistrés avec une méthode privée ou protégée nommée
firetypeEvent
.
Les différents types d'évènements
modifierIl existe un grand nombre de types d'évènements représentés par des classes dérivant de la classe java.util.EventObject
.
Cette section ne citera que les principaux types parmi ceux concernant les interfaces graphiques avec Swing.
La hiérarchie des types d'évènements contient un certain nombre de classes, chacune pouvant ajouter une ou plusieurs informations sur l'évènement.
Classe | Information(s) sur l'évènement définie(s)/ajoutée(s) par la classe | |||||
---|---|---|---|---|---|---|
java.util.EventObject
|
Source de l'évènement : public Object getSource();
| |||||
└─ | java.awt.AWTEvent
|
Identification de l'évènement (ID), consommation de l'évènement | ||||
├─ | java.awt.event.ActionEvent
|
Heure de l'évènement et modificateurs (boutons de souris, touches enfoncées : Shift, Alt, Ctrl...) | ||||
│ | (ID: ACTION_PERFORMED) | |||||
└─ | java.awt.event.ComponentEvent
|
Composant source de l'évènement (conversion de type) | ||||
└─ | java.awt.event.InputEvent
|
Heure de l'évènement et modificateurs (boutons de souris, touches enfoncées : Shift, Alt, Ctrl...) | ||||
├─ | java.awt.event.KeyEvent
|
Code de la touche, caractère généré | ||||
│ | (ID: KEY_TYPED, KEY_PRESSED, KEY_RELEASED) | |||||
└─ | java.awt.event.MouseEvent
|
Position de la souris, nombre de clics, indicateur de menu popup | ||||
│ | (ID: MOUSE_CLICKED, MOUSE_PRESSED, MOUSE_RELEASED, MOUSE_MOVED, MOUSE_ENTERED, MOUSE_EXITED, MOUSE_DRAGGED, MOUSE_WHEEL) | |||||
└─ | java.awt.event.MouseWheelEvent
|
Rotation de la molette de la souris (nombre, pixels de défilement) |
Les sous-classes de la classe java.awt.AWTEvent
ont un attribut (ID) qui identifie une notification particulière d'un évènement, chacune correspondant à une méthode de l'interface d'écoute de l'évènement.
Par exemple, pour les évènements provenant de la souris, les méthodes de l'interface java.awt.event.MouseListener
sont appelées avec un objet évènement de classe java.awt.event.MouseEvent
dont la valeur de l'identificateur (ID) correspond à celles-ci :
public void mouseReleased(MouseEvent e); // e.getID() == MouseEvent.MOUSE_RELEASED
public void mousePressed(MouseEvent e); // e.getID() == MouseEvent.MOUSE_PRESSED
public void mouseExited(MouseEvent e); // e.getID() == MouseEvent.MOUSE_EXITED
public void mouseEntered(MouseEvent e); // e.getID() == MouseEvent.MOUSE_ENTERED
public void mouseClicked(MouseEvent e); // e.getID() == MouseEvent.MOUSE_CLICKED
Même principe pour les méthodes de l'interface java.awt.event.MouseMotionListener
pour intercepter les évènements de mouvement de la souris :
public void mouseMoved(MouseEvent e); // e.getID() == MouseEvent.MOUSE_MOVED (Souris déplacée sans bouton enfoncé)
public void mouseDragged(MouseEvent e); // e.getID() == MouseEvent.MOUSE_DRAGGED (Souris déplacée avec bouton enfoncé)
Cela s'applique aussi aux interfaces qui n'ont qu'une seule méthode, comme l'interface java.awt.event.MouseWheelListener
pour la notification de rotation de molette de la souris :
public void mouseWheelMoved(MouseWheelEvent e); // e.getID() == MouseEvent.MOUSE_WHEEL
Cette redondance apparente d'identification du type d'évènement (par la méthode appelée et par la valeur de l'attribut ID) facilite la réutilisation d'une même méthode pour traiter plusieurs évènements de façon similaire.
Implémentation partielle
modifierLes interfaces d'écoute définissant au moins deux méthodes possèdent une classe dont le nom est celui de l'interface où l'on remplace le suffixe Listener
par Adapter
.
Cette classe définit des méthodes vides et permet aux applications de la surcharger pour ne définir que certaines méthodes de l'interface.
Exemple :
addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e)
{
fermerFenetre();
}
});