Fenêtres - Évènements
Objectifs du chapitre
-
Créer des applications graphiques composées uniquement d’une fenêtre principale (JFrame).
-
Écouter les évènements.
-
Organiser les différentes classes de l’application graphique.
AWT - SWING
Abstract Window Toolkit (AWT) contient un grand nombre de classes permettant de développer une application graphique.
SWING est une version plus récente de ces classes. Attention, SWING s’ajoute à AWT ! Les classes de SWING héritent de celles de AWT. La gestion des évènements reste du ressort des classes de AWT.
Java propose une autre API graphique : JavaFX, qui fait partie du JDK depuis la version 8 de Java. Pour autant, elle n’a pas rendu l’API Swing obsolète. Pour la conception d’applications graphiques et la programmation évènementielle, Swing est une API parfaitement adaptée.
Définitions
1. Component
Un composant (component) est un objet qui a une représentation graphique. Il peut être affiché sur l’écran et interagir avec l’utilisateur. Par exemple : une fenêtre, des boutons, une barre de défilement…
2. Container
Un conteneur (container) est un composant qui peut contenir d’autres composants (une collection de composants). Les composants ajoutés à un container sont notés dans une liste.
3. JComponent
C’est la superclasse de la plupart des composants de SWING. C’est une classe abstraite. Pour utiliser un composant qui hérite de JComponent, il faut le placer dans une hiérarchie de containers dont la racine est un container de "haut niveau", comme JFrame, JDialog et JApplet.
Hiérarchie des composants (extrait)
Les classes de SWING ont un nom qui commence par J : JFrame, JButton…
Fenêtre : création et affichage
1. Fonctionnement par défaut
La classe JFrame permet de créer la fenêtre principale d’une application.
L’instanciation d’un objet JFrame ne produit aucun affichage graphique. C’est une création d’objet, une réservation d’espace mémoire.
import javax.swing.*;
public class Fenetre1
{
public static void main(String args[])
{
JFrame maFenetre;
maFenetre = new JFrame("Première fenêtre");
L’appel de la méthode setVisible(true) permet de visualiser la fenêtre. Celle-ci se dessine en haut à gauche de l’écran. Elle contient quelques éléments, en particulier quelques icônes, le logo de Java, le tout dans une apparence (look & feel) qui ressemble à celle de notre plateforme. Pour ce faire, la machine virtuelle a utilisé des paramètres par défaut qu’il est possible de modifier.
maFenetre.setVisible(true);
}
}
Voici le résultat de l’exécution de ce programme :
Dès que la fenêtre est visible, on peut l’agrandir, la déplacer, la réduire en icône…
Ces possibilités révèlent...
Évènements
1. Introduction
La notion d’évènement est liée à des changements d’état de variables.
Chaque action de l’utilisateur (clavier, souris) provoque des changements d’état de registres et de variables du système d’exploitation. Le programme d’écoute des évènements détecte ces changements.
2. Objets évènements
a. EventObject, MouseEvent, KeyEvent
Quand le programme d’écoute détecte un évènement, il crée un objet pour en stocker les caractéristiques. En Java, un évènement est un objet d’une classe qui hérite de la classe EventObject.
Exemples
-
Si l’utilisateur clique en un point de la fenêtre, il y a création d’un objet de type MouseEvent qui contient les caractéristiques du clic : position de la souris, bouton utilisé... La classe MouseEvent possède toutes les méthodes nécessaires pour accéder à ces propriétés.
-
L’utilisation des touches du clavier provoque la création d’évènements de type KeyEvent.
MouseEvent et KeyEvent sont des évènements de base.
b. Évènements adaptés aux composants
L’écran suivant présente deux boutons OUI et NON :
Connaissant les coordonnées et la dimension...
Conception de programmes avec écoute d’évènements
Les trois exemples qui suivent illustrent l’écoute d’évènements WindowEvent.
Les différentes écritures permettent la recherche d’une démarche de conception d’un programme graphique avec écoute d’évènements.
1. Fenêtre avec écoute des évènements WindowEvent : WindowListener
a. Présentation
La classe Fenetre hérite de JFrame. La documentation concernant JFrame parle d’évènements WindowEvent. Écoutons-les...
La classe EcouteFenetre est la classe ecouteur des évènements WindowEvent.
La méthode main() de la classe principale (Fenetre3) crée l’objet Fenetre, crée l’objet Ecouteur, et les associe.
Il n’est pas toujours évident de visualiser les évènements et de voir à quelle action de l’utilisateur ils correspondent. Rien ne vaut un petit essai ! C’est ce qui est fait dans la classe EcouteFenetre, en plaçant des ordres d’impression dans chaque méthode de l’interface.
b. Classe principale
public class Fenetre3
{
public static void main(String args[])
{
Fenetre maFenetre;
EcouteFenetre ecouteur;
Création de la fenêtre et de l’écouteur :
maFenetre = new Fenetre("Troisième fenêtre");
ecouteur = new EcouteFenetre();
L’écouteur est associé à la fenêtre :
maFenetre.addWindowListener(ecouteur);
maFenetre.setVisible(true);
}
}
c. Classe Fenetre
public class Fenetre extends JFrame
{
public Fenetre(String titre)
{
super(titre);
setBounds(400, 400, 300, 200);
}
}
La classe Fenetre hérite de JFrame. Son constructeur modifie les coordonnées et la taille par défaut de JFrame.
d. Classe EcouteFenetre
public class EcouteFenetre implements WindowListener
{
La méthode WindowClosing()...
EDT (Event Dispatching Thread)
1. Thread
Un thread désigne une suite d’instructions d’un programme qui sont exécutées séquentiellement. Tous les programmes Java ont au moins un thread, appelé main thread (thread principal), créé par la machine virtuelle (JVM) au démarrage de l’application (appel de la méthode main()).
Toutes les applications réalisées dans les chapitres précédents sont exécutées au sein du thread main.
Le langage Java est multi-thread, ce qui signifie que la machine virtuelle autorise une application à avoir plusieurs threads qui s’exécutent en parallèle. La création d’un thread se fait par l’instanciation d’une classe qui implémente l’interface Runnable.
2. Event Dispatching Thread (EDT)
a. Visualisation des threads de l’application
Le programme qui écoute les actions de l’utilisateur et agit en conséquence s’exécute au sein d’un thread appelé EDT : Event Dispatching Thread.
Le programme suivant contient des instructions qui permettent d’afficher les noms des threads où s’exécutent quelques méthodes :
public class Fenetre5Threads
{
public static void main(String args[])
{
System.out.println("main() : " + Thread.currentThread().getName());
Fenetre maFenetre = new Fenetre("Fenetre5Threads");
}
}
public class Fenetre extends JFrame implements WindowListener
{ ...
Travail pratique : Souris
1. Objectif
L’objectif est de développer une application qui utilise les évènements liés à la souris tout en utilisant la documentation de Java.
2. Sujet
-
Déplacer la fenêtre par "draggage", la souris étant positionnée dans la zone de contenu de la fenêtre.
-
Changer le titre de la fenêtre, en cliquant dans la zone de contenu de la fenêtre. Le titre passe alternativement de Deplacement vertical à Deplacement horizontal.
-
Déplacer la fenêtre en faisant rouler la roue de la souris, verticalement si le titre de la fenêtre est : Deplacement vertical, horizontalement sinon.
3. Recherche de documentation
-
Pour la gestion des évènements souris, consulter la documentation de la classe MouseEvent, des interfaces MouseListener, MouseMotionListener.
-
Pour les évènements liés à la roue de la souris, consulter la documentation de la classe MouseWheelEvent et de l’interface MouseWheelListener.
4. Conseils
-
Par une collection d’impressions à la console, visualiser les évènements "écoutés".
-
Déclarer l’écouteur d’évènements WindowEvent dans une classe à part.
-
Faire de la classe Fenetre son propre écouteur d’évènements MouseEvent et MouseWheelEvent.
5. Souris : proposition de correction
a. Test des évènements MouseEvent
Ce programme de test permet de visualiser quelques caractéristiques des évènements MouseEvent.
Classe principale
public class TestSouris
{
public static void main(String args[])
{
SwingUtilities.invokeLater
(
new Runnable()
{
public void run()
{ ...