Modèle/Vue/Contrôleur Frederic.Mallet@unice.fr http://deptinfo.unice.fr/~fmallet/java/ 1
Interfaces graphiques Séparation du modèle et de la vue Changer, dynamiquement ou non, le «look&feel» ou le thème Windows, MacOS, Motif, Java/Metal, Décomposer la complexité Se concentrer sur la fonctionnalité L aspect est secondaire : + ou - simple, avec ou sans RAD Gestion de vues multiples HTML, WML, Swing, XML, 2
Exemple Plusieurs vues Joseph Bergin : http://csis.pace.edu/~bergin/ 3
MVC - Bref historique Introduit par Trygve Reenskaug, 70s Xerox Parc, environnement SmallTalk-80 Depuis, plusieurs adaptations et interprétations Dont MVP : Modèle/Vue/Présentation Modèle Mémorise l état courant (d une partie) de l application Vue Affiche l état courant du modèle Contrôleur/Présentation Définit quand et comment le modèle et la vue sont modifiés 4
PAC : Un autre modèle d agent [Coutaz 88] Trois facettes : Présentation (C + V de MVC) Abstraction (M de MVC) Contrôle : communication entre agent et liaison entre A et P Hiérarchisation : MVC ne définit de hiérarchie, ni les relations entre plusieurs agents MVC! Arbre : relation père-fils Heuristique de conception Communication par message 5
PAC et MVC : vue multiple A C C V1 C P C P M V2 6
MVC - Fonctionnement Notifie les vues ou le contrôleur Modèle État courant Notifie les changements Modifie l état Vue Dessine le modèle Sélectionne Contrôleur Traduit les interactions en actions sur le modèle S intègre au framework graphique : e.g. Swing 7
Le contrôleur Doit s'intégrer à l'environnement graphique sélectionné : framework AWT : Ancien système graphique de Java Swing : Nouveau système graphique de Java SWT : Framework graphique de Eclipse (IBM) J2ME : classes pour les téléphones ou les PDA Il faut donc connaître ce framework Connaître les classes principales Connaître les mécanismes d'extensions prévus C'est un travail long et fastidieux 8
L'environnement graphique de Java A l'origine : AWT (paquetage java.awt) Un paquetage est un ensemble de classes regroupées autour du même thème Swing a été rajouté : JDK 1.1 (javax.swing) Moins gourmand en mémoire Plus modulaire (basé sur MVC) Le composant graphique le plus simple est représenté par la classe java.awt.component Le composant graphique swing le plus simple : javax.swing.jcomponent qui hérite de java.awt.component 9
java.awt.component Définit un élément graphique Une dimension Accesseur: Dimension getsize() Modificateurs: void setsize(dimension) ou void setsize(int,int) Une position Accesseur: java.awt.point getlocation() Modificateurs: void setlocation(java.awt.point) ou void setlocation(int, int) Dessiner le contenu void paint(java.awt.graphics g) 10
java.awt.graphics Contexte graphique («morceau d écran») Permet de dessiner Changer de crayon : void setcolor(color) drawrect, drawoval, drawpolygon, drawstring, fillrect, filloval drawimage(img, x, y, ImageObserver) Obtenu automatiquement (repaint(), redimensionnement, etc.) 11
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] 12
javax.swing.jcomponent Hérite de Container Méthodes de commodité setpreferredsize setdoublebuffered(true/false) / isdoublebuffered() setopaque(true / false) Dessin à l écran : paint appel paintcomponent paintborder paintchildren 13
Hiérarchie partielle 14
Petites listes des JComponents Les boutons JButton /JToggleButton / JCheckBox / JRadioButton java.awt.buttongroup (méthode add) Les icones : javax.swing.imageicon créée avec le nom d un fichier image par exemple Les champs textuels JTextField/ JTextArea Menus : les JMenuBar, JMenu, JMenuItem Etc http://docs.oracle.com/javase/tutorial/uiswing/ 15
Les fenêtres graphiques : JFrame Barre de titre Barre de menu Panneau de contenu (contentpane : Container) Les fenêtres sont des JWindow Les JFrame sont des (hérite de) JWindow avec Un titre, un menu (éventuel), un contenu Le contentpane est un Container contient des composants graphiques (java.awt.component) JFrame fen = new JFrame("fenetre"); fen.getcontentpane().add(new JButton("Ok")); 16
JFrame : quelques méthodes setvisible(boolean b) Cache ou fait apparaître une fenêtre settitle(string title) Modifie le titre de la fenêtre setsize(int width, int height) Modifie la taille de la fenêtre pack () Choisit la taille préférée en fonction du contenu 17
Positionnement dans un containers Ils peuvent contenir plusieurs composants Mais avec quelle disposition? Il délègue le travail à un LayoutManager null : les composants sont positionnés par un système de coordonnées setbounds(10, 20, 100,200); FlowLayout : les composants ont leur taille préférée et sont disposés dans l'ordre d'ajout BorderLayout : Nord, Sud, Est, Ouest, Centre GridLayout : forme tabulaire ligne x colonne La méthode setlayout permet de choisir Par défaut, contentpane utilise BorderLayout 18
java.awt.borderlayout JFrame fen = new JFrame(); Container cp = fen.getcontentpane(); cp.add(new JButton("1"), "Center") ; cp.add(new JButton("2"), "North") ; cp.add(new JButton("3"), "South") ; cp.add(new JButton("4"), "East") ; cp.add(new JButton("555"), "West") ; fen.setvisible(true); North et South ont leur hauteur préférée East et West ont leur largeur préférée Center remplit le reste 19
java.awt.gridlayout JFrame fen = new JFrame(); Container cp = fen.getcontentpane(); cp.setlayout(new GridLayout(2,3)); cp.add(new JButton("1")) ; cp.add(new JButton("2")) ; cp.add(new JButton("3")) ; cp.add(new JButton("4")) ; cp.add(new JButton("555")) ; fen.setvisible(true); Toutes les cellules ont la même taille Cette taille dépend de la taille du Container 20
java.awt.flowlayout JFrame fen = new JFrame(); Container cp = fen.getcontentpane(); cp.setlayout(new FlowLayout()); cp.add(new JButton("1")) ; cp.add(new JButton("2")) ; cp.add(new JButton("3")) ; cp.add(new JButton("4")) ; cp.add(new JButton("555")) ; fen.setvisible(true); Toutes les cellules ont leur taille préférée 21
Capter les évènements javax.swing java.awt.event * écouteurs * Lorsqu'on clique sur un bouton Il notifie ses écouteurs (de type ActionListener) Pour devenir un écouteur Il faut s'enregistrer (addactionlistener) Il faut implémenter l'interface ActionListener Le même écouteur peut écouter différents boutons 22
Exemple d'écouteur : CacheFrame ActionListener Un écouteur qui ferme une fenêtre import javax.swing.jframe; import java.awt.event.*; class CacheFrame implements ActionListener { private JFrame fenetre ; CacheFrame(JFrame f) { this.fenetre = f; } public void actionperformed(actionevent ae) { this.fenetre.setvisible(false); } } 23
Enregistrer l'écouteur JFrame f = new JFrame(); CacheFrame ecouteur = new CacheFrame(f); JButton cb = new JButton("Cliquez-moi"); f.getcontentpane().add(cb); cb.addactionlistener(ecouteur); f.setvisible(true); Lorsqu'on clique sur cb Il notifie ses écouteurs enregistrés : ici ecouteur C'est-à-dire, il exécute leur méthode actionperformed Ici, cette méthode cache la fenêtre : fenetre.setvisible(false) 24