Retour sur MVC. POO3 Introduction aux IHM et à la réflexivité Java Vos premiers pas en Swing.

Slides:



Advertisements
Présentations similaires
Mais vous comprenez qu’il s’agit d’une « tromperie ».
Advertisements

ORTHOGRAM PM 3 ou 4 Ecrire: « a » ou « à » Référentiel page 6
Réaliser en Java un programme client d’une Base de Données
Conception d’IHM en Java
Additions soustractions
Distance inter-locuteur
1 Plus loin dans lutilisation de Windows Vista ©Yves Roger Cornil - 2 août
Evénements Java Beans Java RMI
Gestion des événements (suite)
Audrey Occello Cédric Joffroy Anne-Marie Dery
POO3 Introduction aux IHM et à la réflexivité Java
Conception et evaluation d’ IHM Pourquoi. Comment
Les numéros 70 –
Cours MIAGE « Architectures Orientées Services » Henry Boccon-Gibod 1 Architectures Orientées Services Composants de Service Exemple pratique de développement.
Page 1 Les applets Jacques Lonchamp. Page 2 Présentation Une applet est téléchargée à partir dune machine distante qui fournit le code. Ce chargement.
Voisin-Polian : Introduction à Java 1 Introduction à Java - AWT - Frédéric VOISIN – Nicole POLIAN FIIFO - « Remise à Niveau »
Les Interfaces graphiques Les Swing. Les interfaces graphiques: Introduction Une application est une boîte noire. Prend des entrées et produit des sorties.
Les composants Graphiques Atomiques
contrat Creative Commons Paternité-Pas d'Utilisation Commerciale- Partage des Conditions Initiales à l'Identique.
Algorithme et structure de données
Vos premiers pas en Swing
Vos premiers pas en Swing
POO / IHM Architecture Logicielle
POO / IHM Architecture Logicielle
LES TRIANGLES 1. Définitions 2. Constructions 3. Propriétés.
Technologies et pédagogie actives en FGA. Plan de latelier 1.Introduction 2.Les technologies en éducation 3.iPads 4.TNI 5.Ordinateurs portables 6.Téléphones.
Révision (p. 130, texte) Nombres (1-100).
La législation formation, les aides des pouvoirs publics
Page de garde Les librairies AWT et Swing ESSI2, Septembre 2002
Par Fabrice Pasquier Cours IV
JavaBeans Réalise par: EL KHADRAOUY TARIK AOUTIL SAFOWAN.
1 1 Université Evry Val d'Essonne Y. Laborde Une calculatrice (sans MVC) fonctionnant sur la base d'un modèle en Java.
Le soccer & les turbans Sondage mené par lAssociation détudes canadiennes 14 juin 2013.
Écouteurs de click d'une fenêtre
Python Interfaces graphiques
Présentation générale
Les nombres.
Projet poker 1/56. Introduction Présentation de léquipe Cadre du projet Enjeux Choix du sujet 2.
Graphical User Interface (GUI)
Graphical User Interface
Les chiffres & les nombres
Année universitaire Réalisé par: Dr. Aymen Ayari Cours Réseaux étendus LATRI 3 1.
COURS DE PROGRAMMATION ORIENTEE OBJET :
MAGIE Réalisé par Mons. RITTER J-P Le 24 octobre 2004.

Aire d’une figure par encadrement
Les fondements constitutionnels
MAGIE Réalisé par Mons. RITTER J-P Le 24 octobre 2004.
1/65 微距摄影 美丽的微距摄影 Encore une belle leçon de Macrophotographies venant du Soleil Levant Louis.
Certains droits réservés pour plus d’infos, cliquer sur l’icône.
Création et présentation d’un tableau avec Word 2007
PowerPoint Créer une présentation Créer une diapositive de texte
Annexe Résultats provinciaux comparés à la moyenne canadienne
LIFI-Java 2004 Séance du Mercredi 22 sept. Cours 3.
La formation des maîtres et la manifestation de la compétence professionnelle à intégrer les technologies de l'information et des communications (TIC)
11/04/ L'héritage Cours 7 Cours 7.
Cours 7 Classes locales Clonage Divers: tableaux.
Cours 91 9 Interfaces graphiques avec awt. Cours 92 Plan Introduction : deux bibliothèques graphiques 1.Comment se dessine une fenêtre ?  Un exemple.
Interfaces graphiques. Composants d'interface utilisateur graphique (GUI) 1 Bibliothèques Awt et Swing Procédures communes pour l'utilisation de ces clases.
14 La gestion d’événements
« Validation Formelle de Systèmes Interactifs »
© Sofia ZAIDENBERG CNRS Mai Interface utilisateur graphique en Java Construire une interface graphique en Java (suite) adaptateurs d’événements.
Iup MIAGe 3° année Projet MIAGe Toulouse – Groupe 21 Charte graphique.
 1) Il faut connaître le modèle et son fonctionnement  2) Définir le contrôle que l’on veut faire ouvrir, fermer, afficher, etc.) sur le modèle  3)
Les interfaces de gestion d’événements (la suite).
Scénario Les scénarios permettent de modifier la position, taille … des calques au cours du temps. Son fonctionnement est très proche de celui de Macromedia.
Dreamweaver le retour Avec Les Formulaires Les Calques
FORMULAIRES FOMULAIRE Permet à l’utilisateur d’entrer des renseignements le concernant. Utilisation –Inscription sur un site –Mise à jour d’une base.
Java Swing. Principes de base  Des composants graphiques (exemple: JFrame, JButton …)  Hiérarchie de classes  Des événements et les actions à effectuer.
Les interfaces de gestion d’événements (la suite)
Transcription de la présentation:

POO3 Introduction aux IHM et à la réflexivité Java Vos premiers pas en Swing

Retour sur MVC

Rappel sur le patron MVC MVC pour Modèle-Vue-Contrôleur permet de séparer les données (M), l’interface homme-machine (V) et la logique de contrôle (C) 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 (fournies 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 3

Vous avez vu comment écrire la partie Modèle la partie Vue Reste comment mettre en place le contrôle ?

Observer Observable Rappel

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

Besoin d’événements Le pattern “Observer” décrit Les objets-clés sont 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

Structure

Collaborations

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 Observer void update(Observable o, Object arg); Des listeners : ajouter des listerners, notifier les listeners avec des évenements, réagir aux événements

Observer-Observable et Listeners

Exemple de Listener jan.newmarch.name/java/replayJava/paper.htm

Listeners Supported by Swing Components http://java.sun.com/docs/books/tutorial/uiswing/events/intro.html

CREATION D’UN PANNEAU class ButtonPanel extends JPanel     implements ActionListener    // interface écouteur d'événements { private JButton Boutonjaune;    private JButton BoutonBleu;    private JButton BoutonRouge;  PLACER DES COMPOSANTS DANS LE PANNEAU   public ButtonPanel() // constructeur de la classe ButtonPanel    {  Boutonjaune = new JButton("Jaune");       BoutonBleu = new JButton("Bleu");       BoutonRouge = new JButton("Rouge");       // Insertion des trois boutons dans l'objet ButtonPanel       add(Boutonjaune);       add(BoutonBleu);       add(BoutonRouge); ASSOCIER DES EVENEMENTS AUX COMPOSANTS       // Les sources d'événements sont déclarées à l'écouteur       Boutonjaune.addActionListener(this);        BoutonBleu.addActionListener(this);        BoutonRouge.addActionListener(this);     }   

TRAITEMENT DES EVENEMENTS {   public void actionPerformed(ActionEvent evt)    // Permet de traiter l'événement en fonction de l'objet source    {  Object source = evt.getSource();       Color color = getBackground();       if (source == Boutonjaune) color = Color.yellow;       else if (source == BoutonBleu) color = Color.blue;       else if (source == BoutonRouge) color = Color.red;       setBackground(color);       repaint();    } }

CREATION DE LA FENETRE ET PLACEMENT DU PANNEAU class ButtonFrame extends JFrame {  public ButtonFrame()    {  setTitle("ButtonTest");       setSize(300, 200);       addWindowListener(new WindowAdapter()          {  public void windowClosing(WindowEvent e)             {  System.exit(0);             }          } );       Container contentPane = getContentPane();       contentPane.add(new ButtonPanel());    } } public class ButtonTest {  public static void main(String[] args)    {  JFrame frame = new ButtonFrame();       frame.show();     }

Zoom sur les événements et les Listeners LE CONTRÔLEUR Zoom sur les événements et les Listeners 17

LE CONTRÔLEUR Aperçu général Les types d’événements Les écouteurs associés Méthodes pour implémenter les écouteurs Evénements Sémantiques Les Actions Transition vers le modèle MVC 18

PRINCIPES Programmation par événements : Un écouteur s’abonne à une source La source déclenche l’événement La source le passe aux abonnés Les abonnés réagissent Les composants sont des sources Evénements déclenchés par une action de l’utilisateur 19

LE CONTRÔLEUR Aperçu général Les différents types d’événement Les différents écouteurs associés Méthodes pour implémenter les écouteurs Evénements Sémantiques Les Actions 20

HÉRITAGE DES EVÉNEMENTS 21

Exemples d’événements Définis dans java.awt.event FocusEvent : activation ou désactivation du focus du clavier MouseEvent : mouvement et clics de souris, et entrer/sortir d’un composant KeyEvent : événements clavier WindowEvent : dés/activation, ouverture, fermeture, dés/iconification de fenêtres ComponentEvent : changement de taille, position ou visibilité d’un composant 22

AWTEvent dérive de java.util.EventObject contient par héritage getSource() qui renvoie la source de l’événement (objet où l’événement s’est produit) définit des constantes permettant d’identifier des classes d’événements : MOUSE_EVENT_MASK MOUSE_MOTION_EVENT_MASK WINDOW_EVENT_MASK … 23

GESTION GLOBALE AVEC ENABLEEVENTS() public class toto extends JFrame { public toto() { enableEvents(AWTEvent.WINDOW_EVENT_MASK); protected void processWindowEvent(WindowEvent e) { if (e.getID() == WindowEvent.WINDOW_CLOSING){ dispose(); // libère les ressources System.exit(0); } super.processWindowEvent( e ): // Passe l’ev. 24

Filtrer les événements Une méthode ENABLEEVENTS() Qui filtre les types d’événements particuliers à partir d’ID Pour WindowEvent : WINDOW_OPENED, WINDOW_CLOSING, … 25

LE CONTRÔLEUR Aperçu général Les différents types d’événement Les différents écouteurs associés Méthodes pour implémenter les écouteurs Evénements Sémantiques Les Actions 26

LES ECOUTEURS Depuis (JAVA 1.1) interfaces écouteurs correspondants aux masques d’événements principaux. extensions de java.util.EventListener. 27

LES ECOUTEURS WindowListener : pour les événements de la fenêtre MouseListener : pour les clics et entrées/sorties fenêtre MouseMotionListener : pour les mouvements de la souris KeyListener : pour les touches clavier FocusListener : pour le focus clavier ComponentListener : pour la configuration du composant 28

Contrôle des Fenêtres WINDOWSLISTENER Concerne tout ce qui est en rapport avec la fenêtre : Ouvrir, Fermer, Réduire, Agrandir, … 29

Contrôle des Fenêtres windowActivated(WindowEvent e) : fenêtre active par clic windowDeactivated(WindowEvent e) : fenêtre désactivée windowClosed(WindowEvent e) : fenêtre fermée windowOpened(WindowEvent e) : fenêtre visible 1ere fois windowClosing(WindowEvent e) : fermeture par menu fermé du système windowDeiconified(WindowEvent e) : fenêtre restaurée windowIconified(WindowEvent e) : fenêtre réduite 30

Contrôle de la souris MOUSELISTENER, MOUSEMOTIONLISTENER et MOUSEINPUTLISTENER Concernent tout ce qui est en rapport avec la souris : Clic Déplacement Gestion des boutons…. 31

MOUSELISTENER & MOUSEMOTIONLISTENER MouseListener permet de gérer : Les différents états du clic souris Clic Pressé, Relâché Et également l’entrée/sortie sur un composant MouseMotionListener permet de gérer les mouvements de la souris sur un composant avec bouton appuyé ou relâché 32

MOUSELISTENER mouseClicked(MouseEvent e) : clic souris sur un composant (pressed’N’released) mouseEntered(MouseEvent e) : curseur de la souris rentre sur un composant mouseExited(MouseEvent e) : curseur de la souris sort d’un composant mousePressed(MouseEvent e) : bouton de la souris pressé sur un composant mouseReleased(MouseEvent e) : bouton relâché 33

MOUSEMOTIONLISTENER mouseDragged(MouseEvent e) : bouton de la souris appuyé sur un composant et la souris est déplacée mouseMoved(MouseEvent e) : souris déplacée sur un composant sans bouton enfoncé 34

MOUSEINPUTLISTENER interface écouteur de javax.swing.event. Implémente un MouseListener et un MouseMotionListener ATTENTION : il n’existe pas de méthode addMouseInputListener il faut enregistrer l’écouteur deux fois : avec addMouseListener et avec addMouseMotionListener 35

Contrôle du clavier KEYLISTENER, FOCUSLISTENER Concernent tout ce qui est en rapport avec le clavier : tapé pressé …. 36

KEYLISTENER & FOCUSLISTENER KeyListener, comme pour la souris, on va retrouver la notion de : Pressé, Relâché, Tapé FocusListener permet de gérer le focus et donc de savoir si un composant a obtenu le focus ou s’il la perdu 37

FOCUSLISTENER focusGained(FocusEvent e) : un composant obtient le focus focusLost(FocusEvent e) : un composant perd le focus 38

KEYLISTENER keyPressed(KeyEvent e) : touche du clavier pressée keyReleased(KeyEvent e) : touche du clavier relâchée keyTyped(KeyEvent e) : touche du clavier tapée 39

Contrôle des composants COMPONENTLISTENER Permet de gérer : L’apparition/disparition d’un composant Le déplacement d’un composant Le redimensionnement d’un composant 40

COMPONENTLISTENER componentHidden(ComponentEvent e) : le composant est rendu invisible componentShown(ComponentEvent e) : le composant est rendu visible 41

COMPONENTLISTENER componentMoved(ComponentEvent e) : la position du composant a changé componentResized(ComponentEvent e) : les dimensions du composant ont changé 42

EXEMPLE D’UTILISATION DES ECOUTEURS (1/2) public class Sketcher implements WindowListener { private static SketcherFrame window; // fenêtre de l’application private static Sketcher theApp; // L’objet application public static void main (String[] args) { theApp = new Sketcher(); theApp.init(); } public void init() { window = new SketcherFrame(«Dessin»); Toolkit leKit = window.getToolkit(); Dimension wndSize = leKit.getScreenSize(); window.setBounds(wndSize.width/6, wndSize.height/6, 2*wndSize.width/3,2*wndSize.height/3); window.addWindowListener(this); window.setVisible(true); 43

EXEMPLE D’UTILISATION DES ECOUTEURS (2/2) // Méthode pour l’événement windowClosing public void windowClosing(WindowEvent e ) { window.dispose(); // libère les ressources de la fenêtre System.exit(0); // termine l’application } // fonctions de l’interface listener que nous devons implémenter // mais dont nous n’avons pas besoin … public void windowOpened(WindowEvent e ) {}; public void windowClosed(WindowEvent e ) {}; public void windowIconified(WindowEvent e ) {}; public void windowDeiconified(WindowEvent e ) {}; public void windowActivated(WindowEvent e ) {}; public void windowDeactivated(WindowEvent e ) {}; 44

Quid de l’utilisation Il faut implémenter toutes les méthodes de l’interface, y compris celles dont on ne se sert pas……… 45

Utiliser les classes Adapter Elles implémentent une interface (ici écouteur) mais dont les méthodes n’ont pas de code Etendre la classe Adapter choisie en redéfinissant uniquement les méthodes que l’on souhaite utiliser 46

COMMENT AJOUTER UN ECOUTEUR ?! Pour ajouter un écouteur, on utilise la méthode addXXXListener (XXXListener l) sur le composant désiré Il suffit alors de remplacer les XXX parce que l’on souhaite avoir 47

LE CONTRÔLEUR Aperçu général Les différents types d’événement Les différents écouteurs associés Méthodes pour implémenter les écouteurs Evénements Sémantiques Les Actions 48

POUR IMPLÉMENTER LES ÉCOUTEURS Il existe plusieurs méthodes Etendre d’une classe Adapter ou implémenter une interface Listener Définir des classes internes Définir des classes anonymes 49

IMPLÉMENTER UNE INTERFACE public class MaClass extends MouseListener { ... unObject.addMouseListener(this); void mouseClicked(MouseEvent e)  {} void mouseEntered(MouseEvent e)  {} void mouseExited(MouseEvent e)  {} void mousePressed(MouseEvent e)  {} void mouseReleased(MouseEvent e)  {} } 50 50

ETENDRE UNE CLASSE public class MaClass extends MouseAdapter { ... unObject.addMouseListener(this); public void mouseClicked(MouseEvent e) { // l’implementation de la méthode // associée à l’événement vient ici ... } 51

DÉFINIR UNE CLASSE INTERNE window.addWindowListener(new WindowHandler()); // classe interne WindowHandler // pour les événements de fermeture class WindowHandler extends WindowAdapter { // Méthode pour WINDOW_CLOSING event public void windowClosing( WindowEvent e ) { window.dispose(); System.exit(0); } 52

DÉFINIR UNE CLASSE ANONYME button = new JButton("test"); button.addMouseListener(new MouseAdapter() { @Override public void mouseClicked (MouseEvent e) { // code que l'on souhaite effectuer } }); 53

LE CONTRÔLEUR Aperçu général Les différents types d’événement Les différents écouteurs associés Méthodes pour implémenter les écouteurs Evénements Sémantiques Les Actions 54

Evénements sémantiques Evénements spécifiques liés à des opérations spécifiques sur certains composants Sélection d’éléments dans un menu, Clic sur un bouton, … Trois classes de bases d’événements sémantiques dérivent de AWTEvent 55

Ces trois événements sémantiques sont dans : Hiérarchie Ces trois événements sémantiques sont dans : java.awt.event 56

EVÉNEMENTS ACTIONEVENT une action sur un composant réactif : Clic sur un item de menu, Clic sur un bouton, … Sont émis par les objets de type : Boutons : JButton, JToggleButton, JCheckBox Menus : JMenu, JMenuItem, JCheckBoxMenuItem, JRadioButtonMenuItem … Texte : JTextField 57

EVÉNEMENTS : ITEMEVENT composant est sélectionné ou désélectionné émis par les objets de type : Boutons : JButton, JToggleButton, JCheckBox Menus : JMenu, JMenuItem, JCheckBoxMenuItem, JRadioButtonMenuItem Mais aussi JComboBox, JList 58

EVÉNEMENTS ADJUSTMENTEVENT Se produisent quand un élément ajustable comme une JScrollBar sont ajustés Sont émis par ScrollBar, JScrollBar 59

ECOUTEURS ASSOCIÉS AUX EVÉNEMENTS SÉMANTIQUES Chaque interface contient une unique méthode : ActionListener : void actionPerformed(ActionEvent e) ItemListener : void itemStateChanged(ItemEvent e) AdjustementListener : void adjustementValueChanged (AdjustementEvent e) 60

Les sous-classes de AbstractButton peuvent générer des événements ChangeEvent quand on modifie l’état d’un bouton Les dérivés de JMenuItem génèrent des MenuDragMouseEvent et des MenuKeyEvent Une JList génère des SelectionEvent Les modèles associés aux listes et aux tables génèrent des ListDataEvent et des TableModelEvent (envoyés aux vues quand des changements se produisent sur le modèle) 61

EXEMPLE Cette applet contrôle l’apparition d’une fenêtre supplémentaire (un JFrame) qui apparaît lorsque l’on enfonce le bouton ‘‘Start playing…’’ 62

EXEMPLE Dans le JFrame on trouvera un label et une checkbox qui permettra de cocher si le label est rendu visible ou invisible On pourra aussi iconifier le JFrame ou non Les événements captés écriront leur source et leur type au centre du cadre de l’applet précédent dans la zone de texte 63 63

SOURCE DE L’EXEMPLE PARTIE 1 (1/4) public class ComponentEventDemo extends JApplet implements ComponentListener, ActionListener { JTextArea display; JFrame aFrame; // une fenêtre supplémentaire à afficher public boolean showIt = false; final static String SHOW = "show"; final static String CLEAR = "clear"; String newline = "\n"; public void init() { display = new JTextArea(); display.setEditable(false); JScrollPane scrollPane = new JScrollPane(display); scrollPane.setPreferredSize(new Dimension(200, 75)); getContentPane().add(scrollPane, BorderLayout.CENTER); JButton b1 = new JButton("Start playing..."); b1.setActionCommand(SHOW); b1.addActionListener(this); getContentPane().add(b1, BorderLayout.NORTH); 64

SOURCE DE L’EXEMPLE PARTIE 1 (2/4) JButton b2 = new JButton("Clear"); b2.setActionCommand(CLEAR); b2.addActionListener(this); getContentPane().add(b2, BorderLayout.SOUTH); aFrame = new JFrame("A Frame"); // une autre fenêtre ComponentPanel p = new ComponentPanel(this); // défini + loin aFrame.addComponentListener(this); // aFrame écoute l'Applet p.addComponentListener(this);// et son propre panneau aFrame.getContentPane().add(p, BorderLayout.CENTER); aFrame.pack(); aFrame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { showIt = false; } }); } // fin de init() 65

SOURCE DE L’EXEMPLE PARTIE 1 (3/4) public void actionPerformed(ActionEvent e) { // sur les boutons if (e.getActionCommand() == SHOW) { showIt = true; aFrame.setVisible(true); } else { // CLEAR display.setText(""); // efface le contenu central } public void start() { SwingUtilities.invokeLater(new Runnable() { public void run() { if (showIt) { }); 66

SOURCE DE L’EXEMPLE PARTIE 1 (4/4) protected void displayMessage(String message) { display.append(message + newline); } public void componentHidden(ComponentEvent e) { displayMessage("componentHidden event from " + e.getComponent().getClass().getName()); public void componentMoved(ComponentEvent e) { displayMessage("componentMoved event from " + public void componentResized(ComponentEvent e) { … public void componentShown(ComponentEvent e) { } // fin de ComponentEventDemo 67

SOURCE DE L’EXEMPLE PARTIE 2 (1/2) class ComponentPanel extends JPanel implements ItemListener { // contenu de "aFrame" JLabel label; JCheckBox checkbox; ComponentPanel(ComponentEventDemo listener) { super(new BorderLayout()); // sinon c'est un FlowLayout label = new JLabel("This is a Label", JLabel.CENTER); add(label, BorderLayout.CENTER); checkbox = new JCheckBox("Label visible", true); checkbox.addItemListener(this); add(checkbox, BorderLayout.SOUTH); label.addComponentListener(listener); // listener = le JApplet checkbox.addComponentListener(listener); } 68

SOURCE DE L’EXEMPLE PARTIE 2 (2/2) public void itemStateChanged(ItemEvent e) { // pour la checkbox if (e.getStateChange() == ItemEvent.SELECTED) { label.setVisible(true); // Selon les tutorials sun // Il faut parfois appeler revalidate et repaint // pour assurer le bon affichage du label label.revalidate(); // mise à jour de l'interface label.repaint(); // demande explicite de réaffichage } else { label.setVisible(false); } 69

LE CONTRÔLEUR Aperçu général Les différents types d’événement Les différents écouteurs associés Méthodes pour implémenter les écouteurs Evénements Sémantiques Les Actions 70

LES ACTIONS : CONCEPT Une action est objet de n’importe quelle classe qui implémente l’interface Action. L’interface Action étend l’interface ActionListener un objet Action est aussi un écouteur d’événement d’action de type ActionEvent 71

LES ACTIONS : PRINCIPE Les composants Swing suivants possèdent une méthode add() qui prend en argument un type Action : JMenu , JPopupMenu, JToolBar 72

LES ACTIONS : PRINCIPE Lorsque l’on fait un add() d’un objet Action sur un menu ou une barre d’outils, la méthode add crée un composant à partir de l’objet Action qui est automatiquement du bon type par rapport au composant auquel on l’ajoute (i.e. item de menu ou bouton) 73

LES ACTIONS : INTÉRÊT Ainsi, si on ajoute un objet Action à un JMenu, add() ajoute un JMenuItem au menu. Si on ajoute ce même objet à une JToolBar, c’est un JButton qui lui sera ajouté. Comme l’objet Action est comme son propre écouteur, le bouton et l’item de menu supporteront la même procédure d’action. 74

PROPRIÉTÉS Il y a 7 propriétés standards NAME : String SMALL_ICON : Icon (pour la toolbar) SHORT_DESCRIPTION : String (pour le tooltip) ACCELERATOR_KEY : KeyStroke (accélérateur) LONG_DESCRIPTION : String (aide contextuelle) MNEMONIC_KEY : int (mnémonique de l’action) ACTION_COMMAND_KEY : (keymap associée au comp.) La classe Property est dans java.util. 75

MODIFICATION/RÉCUPÉRATION DES PROPRIÉTÉS D’ACTION void putValue (String key, Object value) : associe l’objet value avec la clé key dans le dictionnaire pour l’objet Action Exemple : pour stocker un nom d’action putValue(NAME, leNom) (On utilise la clé standard NAME pour stocker l’objet leNom) 76

MODIFICATION/RÉCUPÉRATION DES PROPRIÉTÉS D’ACTION Object getValue (String key) : retourne l’objet correspondant à la clé key dans le dictionnaire. Pour retrouver l’icône de la toolbar dans une méthode d’une classe d’action : Icon lineIcon = (Icon) getValue (SMALL_ICON) 77

AUTRES MÉTHODES void addPropertyChangeListener (PropertyChangeListener l) : ajoute un listener qui écoute les changements de propriétés (état d’activation). Utilisé par les conteneurs void removePropertyChangeListener (PropertyChangeListener listener) 78

AUTRES MÉTHODES boolean isEnabled() : retourne true si l’objet d’action est actif et accessible void setEnabled(boolean state) : permet d’agir à la fois sur le bouton de la barre d’outils et l’élément de menu si tous deux ont été créés à partir de la même action 79

ABSTRACTACTION Est défini dans le package javax.swing et implémente l’interface Action Fournit des mécanismes pour stocker les propriétés d’une action Possède trois constructeurs : AbstractAction ( ) AbstractAction ( String name ) AbstractAction ( String name, Icon icon) 80

EXEMPLE D’UTILISATION D’ACTION (1/3) class FileAction extends AbstractAction { // définit les actions FileAction(String name) { // pour les items super(name); // du menu File } FileAction(String name, KeyStroke keystroke) { this(name); if(keystroke != null) putValue(ACCELERATOR_KEY, keystroke); public void actionPerformed(ActionEvent e) { // code pour les actions liées aux items du menu File 81

EXEMPLE D’UTILISATION D’ACTION (2/3) public class SketchFrame extends JFrame { private FileAction newAction, openAction, saveAction; public SketchFrame(String title) { setTitle(title); setJMenuBar(menuBar); setDefaultCloseOperation(EXIT_ON_CLOSE); JMenu fileMenu = new Jmenu("File"); JMenu elementMenu = new JMenu("Elements"); fileMenu.setMnemonic(‘F’); elementMenu.setMnemonic(‘E’); // On construit ici le file menu avec des actions… newAction = new FileAction("New", Keystroke.getKeystroke(‘N’,Event.CTRL_MASK)); addMenuItem(fileMenu, newAction); 82

EXEMPLE D’UTILISATION D’ACTION (3/3) // pour rajouter l’action à la barre d'outils: toolBar.add(newAction); // remarque: pour rajouter son icône, il faudra d’abord l’ajouter à l’action newAction.putValue(Action.SMALL_ICON, new ImageIcon("new.gif")); JButton bouton = toolBar.add(newAction); // et supprimer le label du bouton d’icône bouton.setText(null); // si on avait joué sur le nom (NAME) de l'action, on // aurait perdu le label de texte dans l'item du menu …} private JMenuItem addMenuItem(JMenu menu, Action action) { JMenuItem item = menu.add(action); KeyStroke keystrocke = (KeyStroke) action.getValue(action.ACCELERATOR_KEY); if (keystroke != null) item.setAccelerator(keystroke); return item; } 83

Quid de l’insertion des Listeners dans MVC Rappelez vous du premier Cours

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. 85

Le modèle : la base public class VolumeModel { private int volume; public VolumeModel(){ super(); volume = 0; } public int getVolume() { return volume; public void setVolume(int volume) { this.volume = volume; 86

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) 87

Le listener et l’event 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; 88

Implémentation du système d’écouteurs dans le modèle (1/2) 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(); } 89

Implémentation du système d’écouteurs dans le modèle (2/2) 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())); 90

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 91

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 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(); 92

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 93

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 94

Contrôleur (1/2) 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); 95

Contrôleur (2/2) 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); 96

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 97

JFrameField (1/3) 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); 98

JFrameField (2/3) frame = new JFrame(); contentPane = new JPanel(); 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(); } 99

JFrameField (3/3) public void close() { frame.dispose(); } @Override public void close() { frame.dispose(); } 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())); 100

CONCLUSION 101

LA LIBRAIRE GRAPHIQUE SWING Possède De nombreux widgets graphiques De nombreux containers pour afficher ces widgets Des layouts permettant de faire la mise en page … Permet de réaliser des applications Lourdes qui s’exécutent localement « légères » au-travers des applets Gère les événements au-travers de la couche awt.event par l’utilisation d’écouteurs 102

LA LIBRAIRE GRAPHIQUE SWING Permet de réaliser des applications Lourdes qui s’exécutent localement « légères » au-travers des applets Gère les événements au-travers de la couche awt.event par l’utilisation d’écouteurs 103

D’AUTRES LIBRAIRIES GRAPHIQUES SWT : librairie développé par le projet Eclipse QTJambi : portage de Qt sur Java … Des compléments à Swing SwingX : extension de Swing http://www.swinglabs.org/ JGraph : pour représenter des graphes Un lien intéressant contenant diverses api Java : http://java.developpez.com/outils/api 104

TABLEAU COMPARATIF Caractéristiques Swing SWT QT Layouts De nombreux types de Layouts Grande flexibilité Peu de Layout Mais un Layout puissant avec la notion d’encrage 3 types de Layouts différents Gestion des événements Basé sur des écouteurs Géré par des signaux et des slots Containers Différents types de containers Container web (applet) Nombreux types de containers Quelques containers principalement basés sur QMainWindow

TABLEAU COMPARATIF Caractéristiques Swing SWT QT Elément de base Très grand nombre Moins d’éléments mais basé sur les styles Grand nombre d’éléments Contrainte Liée aux librairies système Liées aux librairies système