1 PROGRAMMATION ÉVÉNEMENTIELLE Géry Casiez http://www.lifl.fr/~casiez IHM Master 1 informatique - Université de Lille 1 Programmation événementielle 2 ¨ Programmation « procédurale » ¤ Le déroulement est contrôlé par une séquence d’instructions écrites ¤ Le programmeur écrit la boucle principale Programme principal initialisations répéter lire une commande traiter une commande jusqu’à la commande finir Programmation événementielle 3 ¨ ¨ Le déroulement est contrôlé par la survenue d’événements (dont les actions de l’utilisateur) Pas de boucle principale (elle est enfouie dans la bibliothèque) Fonctions (réaction aux événements) Programme principal initialisations Programmation événementielle 4 ¨ Événements liés aux périphériques Entrée/sortie du curseur dans une fenêtre ¤ Utilisation d’un des boutons de la souris ¤ Frappe au clavier ¤ Sélection d’un item dans une liste déroulante ¤ … ¤ ¨ Événements liés aux applications Création/destruction de fenêtres ¤ Réaffichage ¤ … ¤ Programmation événementielle 5 ¨ Boucle principale de gestion des événements (enfouie dans la librairie) ¤ Initialisation while () { attendre événement suivant E traiter évènement E } Programmation événementielle 6 ¨ Exemple: JRE Windows Programmation événementielle 7 Programmation événementielle 8 ¨ ¨ Les événements sont placés dans une queue (FIFO) La boucle de gestion des événements prend les événements dans la queue et les traite ¤ Mouse Move (10,15) Mouse Down Left (3,40) Mouse Up Left (10, 50) JRE -> JDK -> Programmation événementielle 9 ¨ L’Event Dispatching Thread (EDT) prend les événements dans la queue et les envoie aux composants Event Dispatching Thread 10 ¨ Attention, les événements de mise à jour de l’affichage sont également gérés par l’EDT Lien composant - application 11 ¨ Fonctions de rappel (callbacks) ¤ Enregistrées dans le composant à sa création (abonnement) ¤ Appelées lorsque l’une des opérations du composant est activée (notification) ¨ Utilisation du patron de conception Observateur Patron de conception Observateur 12 ¨ ¨ ¨ ¨ Appelé également Observer / Observable Plusieurs acteurs: le sujet et les observateurs Ce patron permet à un ensemble d’objets de s’abonner à un sujet pour recevoir automatiquement des notifications chaque fois que ce sujet change d’état Objectif: augmenter la réutilisabilité en diminuant le couplage entre les classes Patron de conception Observateur 13 ¨ ¨ ¨ Listes des observateurs = liste de dépendants Nombre et nature pas forcément connus à la compilation Exemple: la table et les graphiques dépendent du modèle Patron de conception Observateur 14 ¨ Le sujet est une classe abstraite qui fournit une interface pour attacher et détacher des observateurs ainsi que les notifier Pull model: l’observateur doit extraire les informations du sujet Patron de conception Observateur 15 Alternative: push-model: toute l’information est envoyée lors de l’update. Pas d’utilisation de getState() En java… 16 ¨ Java fournit la classe Observable et l’interface Observer Swing et les événements 17 ¨ ¨ Les événements sont représentés par des objets qui fournissent des informations sur l’événement lui même et sur l’objet à l’origine de cet événement Il existe des classes d’événements spécifiques pour chaque type d’interaction avec l’utilisateur Swing et les événements 18 ¨ L’événement généré dépend de la nature physique de l’interaction et surtout de sa signification logique: le type d’objet événement généré n’est pas le même s’il s’agit d’un clic sur un bouton, d’un clic pour sélectionner un menu ou d’un clic pour se positionner dans un champ de saisie de texte Classes d’événements 19 Swing et les événements 20 ¨ ¨ ¨ ¨ ¨ ¨ MouseEvent: actions discrètes de la souris MouseMotionEvent: action continues sur la souris FocusEvent: gain et perte du clavier KeyEvent: actions sur le clavier ActionEvent: pression d’un bouton, choix dans un menu… WindowEvent: événement survenant sur une fenêtre Swing et les événements 21 ¨ La classe à la base des événements: EventObject (java.util) Classes d’événements 22 ¨ Les événements ont comme caractéristique commune d’encapsuler des informations concernant leur contexte d’apparition: ¤ Le composant graphique source (méthode getSource) ¤ Les coordonnées du clic pour un MouseEvent ¤ La valeur de la touche tapée pour un KeyEvent Les Listeners 23 ¨ ¨ A chaque classe d’événement correspond une interface pour le gérer: c’est le listener (observateur) Nécessité de s’abonner… ¤ Public ¨ void addXXXXXListener(XXXXXListener l) … pour être ensuite notifié (appel de méthode) Programmation événementielle sous Java 24 ¨ Exemple: les événements souris sont notifiés par: void mousePressed(MouseEvent e) ¤ void mouseReleased(MouseEvent e) ¤ void mouseClicked(MouseEvent e) ¤ void mouseEntered(MouseEvent e) ¤ void mouseMouseExited(MouseEvent e) ¤ ¨ Un auditeur d’événements souris s’enregistre par ¤ void addMouseListener(MouseListener λ) Exemple: clic sur un bouton 25 ¨ ¨ ¨ Le clic sur un bouton correspond à la classe d’événement ActionEvent L’interface qui gère cet événement est ActionListener (Observateur) L’abonnement se fait par la méthode addActionListener de JButton (Sujet) Exemple: clic sur un bouton 26 …Listeners 27 ¨ ¨ ¨ Nombreuses interfaces de type « …Listeners » Identifier le composant qui va recevoir l’événement Regarder la liste des méthodes addXXXXListeners correspondantes Où gérer les événements? 28 ¨ ¨ ¨ Ecrire une classe qui implémente l’interface correspondante Exemple: Possibilité d’utiliser les adapters pour ne pas avoir à implémenter toutes les méthodes d’une interface ¤ Ex: ¨ WindowListener -> WindowAdapter Inconvénient: ¤ Nécessité de passer le ou les composants à modifier au constructeur Classes internes 29 ¨ ¨ ¨ Classe définie à l’intérieur d’une autre Intérêt: accès aux membres privés de la classe englobante Quand la classe n’est utilisée qu’une seule fois, possibilité de la déclarer en tant que classe interne anonyme Performance 30 ¨ ¨ ¨ Swing gère l’affichage et les événements dans le même thread (l’EDT) Une méthode de gestion des événements lente peut bloquer l’interface Utilisation de threads pour les traitements longs Retour sur MVC 31 ¨ Trois composantes: ¤ Modèle : données de l’application ¤ Vue : présentation, interface utilisateur ¤ Contrôleur : traitements, logique de contrôle, gestion des événements, synchronisation Le MVC dans Swing 32 ¨ ¨ ¨ Swing n’applique pas à la lettre le patron de conception MVC Les composants Swing sont généralement implémentés de telle sorte que la vue et le contrôleur sont indissociables et sont regroupés dans un ComponentUI Le modèle reste séparé Le MVC dans Swing 33 ¨ Un JComponent encapsule ¤ Un ComponentUI ¤ et un Model si cela a un sens MVC et Swing 34 ¨ Modèle et multi-vues ¤ Le Model d’un Jcomponent peut être exporté et partagé avec celui d’un autre Jcomponent ¤ Exemple: JSlider et Jscrollbar: même modèle (Bounded Range Model). Si mise en commun du modèle, on a une synchronisation automatique MVC et Swing 35 ¨ Dans l’API de Jslider: ¨ Changer le modèle du JSlider: ¨ On peut aussi ignorer l’existence des modèles Vision du MVC selon Sun 36 Pluggable Look and Feel 37 ¨ Le UIManager peut changer dynamiquement les ComponentUIs Patron de conception stratégie ¨ ¨ ¨ Strategy en anglais Permet de définir une famille d’algorithmes et de les encapsuler de les façon à les rendre interchangeables Utilisé par le contrôleur Patron de conception stratégie Patron de conception stratégie Exemple: contrôle de température 41 Exercice 42 Exercice 43