Modèle/Vue/Contrôleur F. Mallet [email protected] http://deptinfo.unice.fr/~fmallet/java/ 2011/2012 F. Mallet 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, … 2011/2012 F. Mallet 2 Exemple – Plusieurs vues Joseph Bergin : http://csis.pace.edu/~bergin/ 2011/2012 F. Mallet 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 2011/2012 F. Mallet 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 2011/2012 F. Mallet 5 PAC et MVC : vue multiple A C P C 2011/2012 V1 C P V2 C M F. Mallet 6 MVC - Fonctionnement Notifie les vues ou le contrôleur Modèle •État courant •Notifie les changements Vue •Dessine le modèle Sélectionne 2011/2012 F. Mallet Modifie l’état 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 2011/2012 F. Mallet 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 2011/2012 qui hérite de java.awt.Component F. Mallet 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) 2011/2012 F. Mallet 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.) 2011/2012 F. Mallet 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] 2011/2012 F. Mallet 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 2011/2012 F. Mallet 13 Hiérarchie partielle 2011/2012 F. Mallet 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/ 2011/2012 F. Mallet 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")); 2011/2012 F. Mallet 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 2011/2012 F. Mallet 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 2011/2012 F. Mallet 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 2011/2012 F. Mallet 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 2011/2012 F. Mallet 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” 2011/2012 F. Mallet 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 2011/2012 F. Mallet 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); } } 2011/2012 F. Mallet 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) 2011/2012 F. Mallet 24