poo3 introduction aux ihm et à la réflexivité java anne-marie dery ([email protected])...

57
POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery ([email protected]) Audrey Occello ([email protected]) responsable du module

Upload: jacquette-bonnin

Post on 03-Apr-2015

105 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

POO3 Introduction aux IHM et à la

réflexivité Java

Anne-Marie Dery ([email protected])Audrey Occello ([email protected])

responsable du module

Page 2: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Le matériel progresse sans cesse et se diversifie (station , téléphone portable, table interactive, …)

L’homme lui ne change pas ou presque : il a plus d’exigences (l’informatique lui est familière) Mais ses capacités de perception et d’action sont limitées

ATTENTION Rejet pur et simple par les utilisateurs Coût d'apprentissage (formation)

Perte de productivité Utilisation incomplète (manque à gagner).

Coût de maintenance, Perte de crédibilité.

IHM de plus en plus importante Pourquoi ?

Page 3: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Les besoins en IHM

• Des Interfaces flexibles De bons programmeurs au niveau IHM et

architectureCours logiciel + réflexivité + boîtes à outils

• Des interfaces utilisablesprise en compte des usages (SI5)

• Des interfaces adaptées au support visé bonne connaissance technologique (SI5)

Le design : non enseigné Les designers collaborent avec les informaticiens

Page 4: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Premier cours d’IHM (SI3 / SI4)http://anubis.polytech.unice.fr/cours/2010_2011:si4:pooihm:startArchitecture Logicielle IHM – NFBoite graphique SwingUn détour par la réflexivitéBoite graphique GWT

Cours en amphi Machine fermée (supports format papier)Un TP fil rouge

Des rendus réguliersUne revue de code en fin de TPsUn examen avec documents papiers

à suivre Un parcours IHM et des modules pour aller plus loin (SI5)

Positionnement dans le cursus

Page 5: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Ce que vous allez utiliser de Java

• L’API java• L’héritage • Les exceptions• Les threads• Les inner classes

Quelques flashback ou look forward avant de commencer le vif du sujet

Page 6: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Les packages les plus importants

• L’API – Les bibliothèques graphiques

• java.awt.* - 1ère boite à outil de javaÉléments de base : Component(et Graphics) - Container et Layout

(LayoutManager)• java.swing.* - extension (d’abord JFC puis intégré depuis jdk 1.2)

faire que tout fonctionne de manière identique partout

– Les événements Chaque élément graphique subit des événements : principe du CallBack

appel aux écouteurs par l'écouté lorsque l’événement se produit• java.awt.event.* et java.swing.event

– La réflexivité• java.reflect.* - les classes qui décrivent les concepts de java

Page 7: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

L’héritage bibliothèques graphiques

Page 8: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

L’héritageintrospection et réflexivité java

java.lang.reflect.*

des classes: Object

AccessibleObject

Constructor

Field

Method Array

InvocationTargetException

Modifier

ReflectPermission

une interface : Member

Page 9: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Les classes internesOutil supplémentaire : autre forme d’héritage avec masquage de l’implémentation (y compris au package)Qui permet la définition de «callback» à la voléeUtile pour la programmation événementielle

Se définit :dans une classe, dans une méthode, entre { } ou en paramètre (anonyme)

L’inner a accès aux éléments de la classe qui l’inclutCréation d’une instance d’une inner classe –<Instance de NomDeClasse>.new <Inner>( ) –Ex : Bebete.Etat result = bebete.new Etat();Avec Bebete une classe contenant une classe interne Etat et bebete une instance de la classe Bebete

L’Inner dans un bloc d’instruction•Ne peut pas être utilisée en dehors de la méthode•Utile pour personnaliser des objets sans créer de classe (masquer l’implémentation).

Page 10: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Exemple de classe interne

• Regardez le tutorial Sur les inner classes -http://download-llnw.oracle.com/javase/tutorial/java/javaOO/

innerclasses.html

Sur les event :http://download-llnw.oracle.com/javase/tutorial/uiswing/events/

generalrules.html

Page 11: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Les processus légers ou threads

La classe Thread new Thread(<une instance

Runnable>); –Méthode start( ) qui lance le

processus –Méthode yield( ) pour passer la

main (via le scheduler)

•Pour être plus rapide et Pour ne pas bloquer un processus (interface).

Utilisation de l’interface Runnable–Méthode public void run( )

utilisation de boolean pour les processus «long»public void run( ) {// codewhile( ! canceled) {// code}// code}

import java.util.concurrent.*;

public void run() {try {while(! canceled) {TimeUnit.MILLISECONDS.sleep(100);}} catch(InterruptedException e) {System.err.println("Interrupted");}} Cf. cours internet et réseaux

et cours appli. concurrentes

Page 12: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Exemples• Vous pouvez aller regarder

La partie du tutorial java consacrée à ce point : http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html

Le pointeur donné par M. Riveill : http://rangiroa.polytech.unice.fr/cours/Turorial%20Java/essential/threads/

Page 13: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

•Organiser le code (rangement) Simplifier (diviser pour régner)•Organiser le travail Modifier (une partie)•Ré-utiliser Notions : modularité, évolutivité, flexibilité

Séparation possible –Code pour IHM–Code «Métier»

•Exemple –IHM différente pour une Gestion d’un stock de chaussures ou de bibelots ?–Linux sous gnome ou kde, le système change-t-il ?

•Objectif : éviter de tout modifier si on change la partie fonctionnelle ou la partie IHM

Architecture Logicielle et IHM : Pourquoi ?

Page 14: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Un problème classique

Page 15: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Des architectures logicielleshttp://tel.archives-ouvertes.fr/docs/00/04/82/79/HTML/2_2modelesinterface_referen.html

Tous les modèles partent du principe :un système interactif comporte une partie interface et une partie application pureCette dernière est souvent appelée noyau fonctionnel. Le noyau fonctionnel est considéré comme préexistant, et les modèles de systèmes interactifs décrivent essentiellement la partie interface, ainsi que ses relations avec les objets du domaine.

La plupart des modèles identifient au moins trois types d'éléments :un ``coté utilisateur'‘ (présentations), un ``côté noyau fonctionnel'‘ (interfaces du noyau fonctionnel, abstractions,

modèles), et des éléments articulatoires (contrôleurs, adaptateurs).

Système interactif

utilisateur

Page 16: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Des architectures logicielles : modèles architecturaux

Seeheim

Premier modèle (groupe de travail à Seeheim en 1985) - destiné au traitement lexical des entrées et sorties dans les interfaces textuelles – a servi de base à beaucoup d'autres modèles.

Retour sémantique direct

utilisateur

NF

Page 17: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Des architectures logicielles : modèles architecturaux

Arch

utilisateurComposant d'interaction - ensemble des widgets (objets interactifs) +

communications avec les périphériques physiques – Composant de présentation - représentation logique des widgets indépendante de la plate-forme. Contrôleur de dialogue - responsable du séquencement des tâches et du maintien de la consistance entre les vues multiples. Adaptateur du domaine - responsable des tâches dépendantes du domaine qui ne font pas partie du noyau fonctionnel mais qui sont nécessaires à sa manipulation par l'utilisateur. Noyau fonctionnel représente la partie non interactive de l'application.

Le modèle Arch [1992] 5 composants et 3 types de donnéesobjets du

domaine

objets dudomaine

objets de présentation

objets d'interaction

Page 18: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Des architectures logicielles : modèles à agents

utilisateur

utilisateur

Le modèle MVC (Modèle, Vue, Contrôleur) Smalltalk [Goldberg and Robson, 1981].

modifiabilité + conception itérative + compatibilité avec les langages à objets.

les systèmes interactifs = une hiérarchie d'agents. Un agent MVC = un modèle, une ou plusieurs vues, et un ou plusieurs contrôleursmodèle = noyau fonctionnel de l'agent. (entier, chaîne de caractères ou objets) Le modèle notifie les vues à chaque fois que son état est modifié par le noyau ou par ses contrôleurs. La vue (constituée d'objets graphiques) maintient une représentation du modèle pour l'utilisateur, mise à jour à chaque notification d'état. Le contrôleur reçoit et interprète les événements utilisateur, les répercutant sur le modèle (modification de son état) ou sur la vue (retour instantané).

Page 19: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Des architectures logicielles : modèles à agents

PAC

PAC

utilisteurmodèle à agents PAC (Présentation, Abstraction, Contrôle) [Coutaz, 1987] = hiérarchie d'agents.

présentation = comportement en entrée et en sortie de l'agent pour l'utilisateur. Abstraction = la partie sémantique de l'agent. Contrôle = consistance entre la présentation et l'abstraction,. Abstraction : équivalent modèle de MVC,présentation : fusion des composants vue et contrôleur. Le composant contrôle n'a pas d'existence explicite dans le modèle MVC.

le modèle PAC peut être appliqué à plusieurs niveaux d'un système interactif. Une application interactive peut ainsi être décrite comme une hiérarchie d'agents disposés sur plusieurs couches d'abstractions

PAC/Amodeus = Arch + Pac avec hiérarchie PAC dans le contrôleur

Page 20: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Zoom : Architecture MVC•Smalltalk[Goldberg et Robson1979-1983] –Model : modélisation (données et comportement)–View: représentation manipulable de l'objet–Control : interprétation des entrées

Séparer dans le code–les données (le Modèle),–La ou les Vues,–Le Contrôle

•V s’abonne à M•C s’abonne à V•C modifie M et V

Page 21: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Le contrôleur au centre de la communication

Page 22: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Plusieurs vues – 1 modèle

Page 23: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Exemple

Page 24: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Pour voir le code complet

• http://java.sun.com/developer/technicalArticles/javase/mvc/

Page 25: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Observer Observable

Page 26: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Motivation

• Un effet de bord fréquent de la partition d’un système en une collection de classes coopérantes est la nécessité de maintenir la consistance entre les objets reliés entre eux.

• On ne veut pas obtenir la consistance en liant étroitement les classes, parce que cela aurait comme effet de réduire leur réutilisabilité.

Page 27: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Moyen

Définir une dépendance de “1” à “n” entre des objets telle que

lorsque l’état d’un objet change,

tous ses dépendants sont informés et mis à jour automatiquement

Page 28: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Quand l’appliquer

• Lorsqu’une abstraction possède deux aspects dont l’un dépend de l’autre.– L’encapsulation de ces aspects dans des objets séparés permet de

les varier et de les réutiliser indépendamment. – Exemple : Modèle-Vue-Contrôleur

• Lorsqu’une modification à un objet exige la modification des autres, et que l’on ne sait pas a priori combien d’objets devront être modifiés.

• Lorsqu’un objet devrait être capable d’informer les autres objets sans faire d’hypothèses sur ce que sont ces objets,

Page 29: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Besoin d’événements

• Le pattern “Observer” décrit – comment établir les relations entre les objets dépendants.

• Les objets-clés sont – la source

• Peut avoir n’importe quel nombre d’observateurs dépendants

• Tous les observateurs sont informés lorsque l’état de la source change

– l’observateur.• Chaque observateur demande à la source son état afin de se

synchroniser

Page 30: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Structure

Page 31: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Implémentations Java du pattern

Une classe et une interface : class Observable {... } et interface Observer

Un objet Observable doit être une instance de la classe qui dérive de la classe Observable

Un objet observer doit être instance d’une classe qui implémente l’interface Observervoid update(Observable o, Object arg);

Des listeners : ajouter des listerners, notifier les listeners avec des événements, réagir aux événements

Page 32: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Listeners Supported by Swing Components

• http://java.sun.com/docs/books/tutorial/uiswing/events/intro.html

Page 33: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Des éléments graphiques : ComponentDéfinition d’un élément graphique avecune dimension, une positionDes Coordonnées(Origine coin supérieur gauche, x (width) vers la droite et y (height) vers le bas)

Des morceaux d’écrans : GraphicsContexte graphiquePermet de dessiner –Changer de crayon : couleur, formes géométriques, images, chaînes de caractères- Automatiquement redimensionnés, réaffichés

Que trouve-t-on dans les librairies graphiques ?

Des éléments graphiques Contenant Container : qui contiennent d’autres éléments graphiques organisés

Du Formattage  : LayoutManagerDéfinition de l’organisationEn ligne, en tableau, avec des contraintes,etc

Page 34: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Hiérarchie Swing

Page 35: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Aperçu de Swing Les Containers

Les containers

Ont un LayoutManager–add / remove d’un Component–Unicité de lieu–Indice des components

Méthodes à connaître

•repaint() ! validate() ! •setEnabled(true / false) : activé / désactivé•(Rectangle) getBounds / setBounds(x,y, w, h) : positionne et dimensionne•getWidth() : largeur / getHeight() : hauteur•getX() et getY() : obtenir une coordonnée•setVisible(true / false)•getBackground et setBackground [objet Color, définition RGB]

Page 36: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Aperçu de SwingDes composants

JComponent Hérite de ContainerMéthodes de commoditégetSize retourne une DimensionsetSize : une Dimension ou deux entiers–Une position•getLocation retourne un Point•setLocation avec un Point ou deux entiers–Coordonnées•Origine au coin supérieur gauche•x (width) vers la droite et y (height) vers le bas–Méthode public void paint(Graphicsg)

–setPreferredSize–setDoubleBuffered(true/false) / isDoubleBuffered()–setOpaque(true / false)•Dessin à l’écran : paint appelle–paintComponent–paintBorder–paintChildren

Les boutons–JButton /JToggleButton / JCheckBox / JRadioButton–java.awt.ButtonGroup (méthode add)Les champs textuels –JTextField/ JTextAreaEtc…

Page 37: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Aperçu de Swinget aussi…

Les îcones : javax.swing.ImageIcon créer avec le nom d’un fichier image par exemple

Menus : les JMenuBar, JMenu, JMenuItem

Les Layout :Basé sur PreferredSize ou une maximisation de l’élément•BorderLayout –par défaut dans une fenêtre–ajout en précisant la zone–add("North", comp)•FlowLayout : en ligne•GridLayout : en tableau•GridBagLayout : avec des contraintes•etc.

Page 38: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Exempleimport javax.swing.*;

import java.awt.*; import java.awt.event.*; import java.util.*;

public class SwingButton extends JApplet { public void init() {     // Swing adds JComponents to the containers JcontentPane     Container contentPane = getContentPane();     // Create an instance of JButton     JButton button = new JButton("A Button");     // Add the button to the contentPane. contentPane.add(button);

  } }

Page 39: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Rappel sur le patron MVC• Impose une séparation en 3 couches :

– M : représente les données de l’application. Définit interaction avec la base de données et le traitement des données

– V : représente l’interface utilisateur. Effectue aucun traitement, ne fait que l’affichage des données (fournit par M). Possibilité d’avoir plusieurs vues pour un même M

– C : gère l’interface entre le modèle et le client. Interprète la requête de ce dernier pour lui envoyer la vue correspondante. Effectue la synchronisation entre le modèle et les vues

44

Page 40: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Synchronisation entre la vue et le modèle

• Se fait par l’utilisation du pattern Observer.

• Permet de générer des événements lors d’une modification du modèle et d’indiquer à la vue qu’il faut se mettre à jour

45

Page 41: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Mise en garde

• La mise en œuvre de MVC dans une application n’est pas une tâche aisée : – Introduit un niveau de complexité assez élevée– Implique une bonne conception dès le départ

• Peut prendre du temps au développement• En faire gagner lors de l’évolution de

l’application

• Conseillée pour les moyennes et grandes applications amenées à être maintenues, étendues et pérennes

48

Page 42: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Mise en place• Exemple assez simple d’une application qui permet

de modifier un volume.

• Plusieurs vues pour représenter le volume et après toutes modifications, toutes les vues devront être synchronisées.

• Conseils : dans une grosse application, il est important de faire différents packages pour les différentes préoccupations

49

Page 43: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Le modèle : la base

50

public class VolumeModel { private int volume; public VolumeModel(){ super(); volume = 0; } public int getVolume() { return volume; } public void setVolume(int volume) { this.volume = volume; }}

Page 44: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Pour la notification

• Pour permettre la notification de changement de volume, on utilise des listeners

• On crée donc un nouveau listener (VolumeListener) et un nouvel événement (VolumeChangeEvent)

51

Page 45: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Le listener et l’event

52

import java.util.EventListener;public interface VolumeListener extends EventListener { public void volumeChanged(VolumeChangedEvent event);}

import java.util.EventObject;public class VolumeChangedEvent extends EventObject{ private int newVolume; public VolumeChangedEvent(Object source, int newVolume){ super(source); this.newVolume = newVolume; } public int getNewVolume(){ return newVolume; }}

Page 46: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Implémentation du système d’écouteurs dans le modèle (1/2)

53

import javax.swing.event.EventListenerList;public class VolumeModel { private int volume; private EventListenerList listeners; public VolumeModel(){ this(0); } public VolumeModel(int volume){ super(); this.volume = volume; listeners = new EventListenerList(); } public int getVolume() { return volume; } public void setVolume(int volume) { this.volume = volume; fireVolumeChanged(); }

Page 47: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Implémentation du système d’écouteurs dans le modèle (2/2)

54

public void addVolumeListener(VolumeListener listener){ listeners.add(VolumeListener.class, listener); } public void removeVolumeListener(VolumeListener l){ listeners.remove(VolumeListener.class, l); } public void fireVolumeChanged(){ VolumeListener[] listenerList = (VolumeListener[])

listeners.getListeners(VolumeListener.class); for(VolumeListener listener : listenerList){ listener.volumeChanged(

new VolumeChangedEvent(this, getVolume())); } }}

Page 48: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Ce que l’on a maintenant• Le modèle est maintenant capable d’avertir

tous ses écouteurs à chaque changement de volume

• En fonction de l’application, il est possible d’imaginer plusieurs listeners par modèles et d’autres événements dans les listeners (par exemple quand le volume dépasse certains seuils)

• Remarque : le modèle peut devenir très vite conséquent

55

Page 49: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Pré-requis pour le contrôleur

• Pour éviter d’être dépendant de Swing, on va créer une classe abstraite représentant une vue de volume

56

public abstract class VolumeView implements VolumeListener{ private VolumeController controller = null; public VolumeView(VolumeController controller){ super(); this.controller = controller; } public final VolumeController getController(){ return controller; } public abstract void display(); public abstract void close();}

Page 50: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Le Contrôleur

• Manipulera des objets de type View et non plus de type Swing

• Un seul contrôleur sera créé dans un soucis de simplicité puisque les 3 vues font la même chose.

• Dans le cas de vues complètement différentes, il est fortement conseillé d’utiliser plusieurs contrôleurs

57

Page 51: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Les vues• Nous supposons 3 vues (dans le cadre du cours,

nous n’en montrerons qu’ une) : – Une vue permettant de modifier le volume avec

un champ de texte et valider par un bouton– Une vue permettant de modifier le volume à

l’aide d’une jauge + bouton pour valider– Une vue listant les différents volumes

• Toutes ces vues sont représentées par une JFrame

58

Page 52: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Contrôleur (1/2)

59

public class VolumeController { public VolumeView fieldView = null; public VolumeView spinnerView = null; public VolumeView listView = null; private VolumeModel model = null; public VolumeController (VolumeModel model){ this.model = model; fieldView = new JFrameFieldVolume(this, model.getVolume()); spinnerView = new JFrameSpinnerVolume(this, model.getVolume()); listView = new JFrameListVolume(this, model.getVolume()); addListenersToModel(); } private void addListenersToModel() { model.addVolumeListener(fieldView); model.addVolumeListener(spinnerView); model.addVolumeListener(listView); }

Page 53: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Contrôleur (2/2)

60

public void displayViews(){ fieldView.display(); spinnerView.display(); listView.display(); } public void closeViews(){ fieldView.close(); spinnerView.close(); listView.close(); } public void notifyVolumeChanged(int volume){ model.setVolume(volume); }}

Page 54: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

Les vues• Nous allons faire 3 vues (dans le cadre du cours,

nous n’en montrerons qu’ une) : – Une vue permettant de modifier le volume avec

un champ de texte et valider par un bouton– Une vue permettant de modifier le volume à

l’aide d’une jauge + bouton pour valider– Une vue listant les différents volume

• Toutes ces vues sont représentées par une JFrame

61

Page 55: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

JFrameField (1/3)

62

import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.text.NumberFormat;import javax.swing.*;import javax.swing.text.DefaultFormatter;public class JFrameFieldVolume extends VolumeView

implements ActionListener{ private JFrame frame = null; private JPanel contentPane = null; private JFormattedTextField field = null; private JButton button = null; private NumberFormat format = null; public JFrameFieldVolume(VolumeController controller) { this(controller, 0); } public JFrameFieldVolume(VolumeController controller, int volume){ super(controller); buildFrame(volume); }

Page 56: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

JFrameField (2/3)

63

private void buildFrame(int volume) { frame = new JFrame(); contentPane = new JPanel(); format = NumberFormat.getNumberInstance(); format.setParseIntegerOnly(true); format.setGroupingUsed(false); format.setMaximumFractionDigits(0); format.setMaximumIntegerDigits(3); field = new JFormattedTextField(format); field.setValue(volume); ((DefaultFormatter)field.getFormatter()).setAllowsInvalid(false); contentPane.add(field); button = new JButton("Mettre à jour"); button.addActionListener(this); contentPane.add(button); frame.setContentPane(contentPane); frame.setTitle("JFrameSpinnerVolume"); frame.pack(); }

Page 57: POO3 Introduction aux IHM et à la réflexivité Java Anne-Marie Dery (pinna@polytech.unice.fr) Audrey Occello (occello@polytech.unice.fr) responsable du

JFrameField (3/3)

64

@Override public void close() { frame.dispose(); } @Override public void display() { frame.setVisible(true); } public void volumeChanged(VolumeChangedEvent event) { field.setValue(event.getNewVolume()); } public void actionPerformed(ActionEvent arg0) { getController().notifyVolumeChanged(Integer.parseInt(field.getValue().toString())); }}