# Programmation Java Swing/Gestion des évènements

* Introduction
* Composants
** Arbre
* Fenêtres
* Menus
* Actions
* Types de données et constantes
* Gestion de la disposition des composants
* Gestion des évènements
* Gestion des actions asynchrones
* Apparence de l'interface
* Contenu en HTML
* Créer un composant
** Une case à cocher à trois états
** Dessin d'un composant
** Dessin d'une étoile
** Dessin de texte et effets
* Créer une image
* Introduction
* Composants
** Arbre
* Fenêtres
* Menus
* Actions
* Types de données et constantes
* Gestion de la disposition des composants
* Gestion des évènements
* Gestion des actions asynchrones
* Apparence de l'interface
* Contenu en HTML
* Créer un composant
** Une case à cocher à trois états
** Dessin d'un composant
** Dessin d'une étoile
** Dessin de texte et effets
* Créer une image
[ Modifier le sommaire ]
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

De 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.
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 classe java.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 classe typeEvent.
* 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

Il 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 | Classe | Classe | Classe | Classe | Classe | Information(s) sur l'évènement définie(s)/ajoutée(s) par la classe |
| java.util.EventObject | java.util.EventObject | java.util.EventObject | java.util.EventObject | java.util.EventObject | java.util.EventObject | Source de l'évènement : public Object getSource; |
| └─ | java.awt.AWTEvent | java.awt.AWTEvent | java.awt.AWTEvent | java.awt.AWTEvent | java.awt.AWTEvent | Identification de l'évènement (ID), consommation de l'évènement |
| | ├─ | java.awt.event.ActionEvent | java.awt.event.ActionEvent | java.awt.event.ActionEvent | 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 | java.awt.event.ComponentEvent | java.awt.event.ComponentEvent | java.awt.event.ComponentEvent | Composant source de l'évènement (conversion de type) |
| | | └─ | java.awt.event.InputEvent | java.awt.event.InputEvent | java.awt.event.InputEvent | Heure de l'évènement et modificateurs (boutons de souris, touches enfoncées : Shift, Alt, Ctrl...) |
| | | | ├─ | java.awt.event.KeyEvent | java.awt.event.KeyEvent | Code de la touche, caractère généré |
| | | | │ | | | (ID: KEY_TYPED, KEY_PRESSED, KEY_RELEASED) |
| | | | └─ | java.awt.event.MouseEvent | 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 :
Même principe pour les méthodes de l'interface java.awt.event.MouseMotionListener pour intercepter les évènements de mouvement de la souris :
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 :
Cette redondance apparente d'identification du type d'évènement, à la fois 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 tout en distinguant les évènements.

## Implémentation partielle

Les 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 :

## Déclenchement d'une action sur appui d'une touche

Il est courant d'utiliser des raccourcis clavier pour effectuer des actions, comme par exemple utiliser la touche Suppr pour supprimer l'élément sélectionné.
La méthode registerKeyboardAction permettant d'associer une action à un raccourci clavier est devenue obsolète. Elle s'utilisait comme illustré dans le code d'exemple suivant :
Cette méthode est remplacée par l'utilisation des méthodes getInputMap et getActionMap récupérant les tables associatives permettant, respectivement, d'associer une touche à une commande et une commande à une action.
La méthode getInputMap(int condition) retourne la table associative pour la condition spécifiée :

### WHEN_IN_FOCUSED_WINDOW

    Touches prises en compte quand le composant est affiché dans la fenêtre courante. Le composant n'a pas forcément le focus.

### WHEN_FOCUSED

    Touches prises en compte quand le composant a le focus.

### WHEN_ANCESTOR_OF_FOCUSED_COMPONENT

    Touches prises en compte quand le composant contient le composant qui a le focus.
La méthode getInputMap appelée sans argument équivaut à getInputMap(WHEN_FOCUSED).
Certaines touches sont déjà utilisées par les composants Java Swing. Il faut éviter d'utiliser les mêmes car l'action voulue peut ne pas se déclencher ou seulement dans certaines conditions de focus.
Pour éviter un tel conflit, il suffit souvent de combiner la touche avec un modificateur comme Shift (InputEvent.SHIFT_DOWN_MASK) ou Ctrl (InputEvent.CTRL_DOWN_MASK) ou les deux à la fois.
La section suivante liste la plupart des raccourcis de touches pouvant potentiellement entrer en conflit.

## Touches utilisées par les composants Swing

Certaines touches sont déjà utilisées par les composants Java Swing pour interagir avec l'interface graphique sans utiliser la souris.
| Composants | Touche | Action |
| ceux permettant d'associer une lettre : JButton | Alt A..Z | Déclencher l'action |
| JMenuBar | Alt | Passer le focus à la barre de menus / Rendre le focus au composant précédent. |
| tous ceux gérant le focus : JButton, JCheckbox, JRadioButton, JToggleButton, JComboBox, JList | ↹ | Passer le focus au composant suivant dans la chaîne |
| tous ceux gérant le focus : JButton, JCheckbox, JRadioButton, JToggleButton, JComboBox, JList | ⇑↹ | Passer le focus au composant précédent dans la chaîne |
| tous ceux gérant le focus : JButton, JCheckbox, JRadioButton, JToggleButton, JComboBox, JList | ←↑→↓ | Navigation dans le composant |
| JCheckbox, JRadioButton, JToggleButton | | Cocher / décocher |
| JButton | | Déclencher l'action du bouton |
| JButton | ↵ | Déclencher l'action du bouton par défaut (par exemple : le bouton "OK" d'une boîte de dialogue). |
| JComboBox | Échap | Cacher la liste déroulante |
| JComboBox | Alt↓ | Afficher la liste déroulante |
| JComboBox | Alt↑ | Cacher la liste déroulante |
| JComboBox, JList | ↓ | Sélectionner l'item suivant dans la liste |
| JComboBox, JList | ↑ | Sélectionner l'item précédent dans la liste |
| JSplitPane | F8 | Passer le focus à la barre de séparation |
Source :
* ↑ https://www.ibm.com/docs/en/sdk-java-technology/8?topic=applications-default-swing-key-bindings