Lorsque la fenêtre d'une application Java est active, les interactions de l'utilisateur avec la souris forment des évènements de type MouseEvent. Le fait d'appuyer ou de relâcher un bouton sont des évènements distincts, de même qu'un mouvement du curseur sera décomposé en plusieurs évènements de mise à jour de position (plus ou moins nombreux en fonction de la fréquence de communication avec le périphérique).
Vu le nombre important d'évènements à traiter et le coût en performance que cela implique, on a choisi de diviser ces évènements en trois catégories qui ont chacune leur interface de capture : l'interface MouseListener gère les boutons, l'interface MouseWheelListener gère la molette, et l'interface MouseMotionListener gère les mouvements du pointeur.
Lorsqu'un évènement est généré, il est d'abord proposé au composant graphique que le curseur survole actuellement. Si aucun observateur approprié n'est disponible pour ce composant, l'évènement est proposé au composant qui contient celui-ci, et ainsi de suite jusqu'à proposer l'évènement à la fenêtre elle-même. Cela signifie que plusieurs composants graphiques ne peuvent pas réagir au même évènement. Par contre, plusieurs observateurs «branchés» sur un seul composant peuvent tous réagir en même temps.
On peut connecter un observateur de type MouseListenerà n'importe quel composant graphique (JComponent et ses dérivés) ou à une fenêtre (JFrame). Pour définir un tel observateur, il faut préciser le comportement à adopter dans cinq circonstances distinctes :
void mouseClicked(MouseEvent evenement); // un bouton cliqué void mouseEntered(MouseEvent evenement); // debut du survol void mouseExited(MouseEvent evenement); // fin du survol void mousePressed(MouseEvent evenement); // un bouton appuyé void mouseReleased(MouseEvent evenement); // un bouton relâché
Dans le paramètre de ces méthodes (de type MouseEvent), on trouve des informations importantes pour choisir la conduite à adopter, en particulier en invoquant getButton, getClickCount et getModifiersEx.
La molette d'une souris est considérée comme un bouton normal lorsque l'on appuie dessus, mais il faut une interface particulière pour gérer sa rotation.
L'interface MouseWheelListener contient une seule méthode :
void mouseWheelMoved(MouseWheelEvent evenement);
La classe MouseWheelEvent est une spécialisation de la classe MouseEvent, qui ajoute notamment la méthode getWheelRotation pour obtenir le nombre de «clics» qui se sont succédés (en négatif si la rotation a eu lieu vers le haut).
Les mouvements du curseur peuvent être suivis par des évènements, mais leur grande fréquence implique que le code de l'observateur soit très rapide pour éviter les ralentissements.
Dans l'interface MouseMotionListener, on distingue deux formes de mouvements, suivant qu'un bouton est maintenu appuyé durant le mouvement, ce qui conduit à deux méthodes de traitement :
void mouseDragged(MouseEvent evenement); // mouvement appuyé void mouseMoved(MouseEvent evenement); // mouvement libre
Dans ces situations, l'information la plus utile peut être extraite du paramètre de type MouseEvent par les méthodes getX et getY (plus rarement getXOnScreen et getYOnScreen).
Volume. Écrivez une application qui affiche une valeur comprise entre 0 et 10 sous la forme de dix disques alignés le long d'une ligne horizontale.
La valeur devra pouvoir être ajustée à l'aide la molette de la souris et l'affichage sera modifié en conséquence.
Playlist. Écrivez une application qui contient une dizaine d'étiquettes (JLabel) empilées verticalement pour représenter une playlist (prenez votre album favori comme exemple).
Chaque étiquette aura plusieurs modes indiqués par sa couleur de fond : en gris clair pour un morceau sélectionné, en cyan pour un morceau non sélectionné et survolé, en blanc sinon.
Au départ de l'aplication aucun morceau n'est sélectionné. Par la suite, un morceau sera sélectionné en cliquant dessus (un seul morceau peut être sélectionné à la fois).
Remarque La méthode setBackground n'a pas d'effet visible sur une étiquette à moins de la rendre opaque (par la méthode setOpaque).
Rectangle. Dans de nombreuses applications, vous avez l'habitude de délimiter une zone rectangulaire en «tirant» la souris d'un coin de la zone au coin opposé. Écrivez une application sur ce modèle qui permet à l'utilisateur de dessiner un rectangle bleu. Chaque nouveau rectangle devra remplacer le précédent.
Multiple. On souhaite améliorer le deuxième exercice en permettant de sélectionner plusieurs morceaux à la fois. Si on clique sur un morceau en maintenant la touche «Contrôle» enfoncée, le morceau doit être ajouté à la sélection (ou retiré de la sélection s'il en fait déjà partie).
Balle. Écrivez une application contenant cette image en fond et cette image par dessus. Faites en sorte que l'utilisateur puisse déplacer la balle comme il le ferait pour une icône.