Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
1
Vos premiers pas en Swing
2
Vous avez vu comment écrire la partie Modèle On va voir la partie Vue
3
Que trouve-ton dans les librairies graphiques : RAPPEL
Des éléments graphiques : Component Définition d’un élément graphique avec une dimension, une position Des Coordonnées (Origine coin supérieur gauche, x (width) vers la droite et y (height) vers le bas) Des éléments graphiques Contenant Container : qui contiennent d’autres éléments graphiques organisés Des morceaux d’écrans : Graphics Contexte graphique Permet de dessiner –Changer de crayon : couleur, formes géométriques, images, chaînes de caractères - Automatiquement redimensionnés, réaffichés Du Formattage : LayoutManager Définition de l’organisation En ligne, en tableau, avec des contraintes,etc
4
PRINCIPES GÉNÉRAUX Pour la création des composants :
On choisit le container – on le crée On précise le panneau dans lequel on dispose les composants (contenu) On crée les événements sur les composants. IL PEUT Y AVOIR PLUSIEURS PANNEAUX DANS UNE FENETRE 4
5
PRINCIPES GÉNÉRAUX Exemple pour la création des composants
Création d’un JFrame, Construction du contenu dans un panneau (JPanel) ajouté au panneau de base : le contentPane Traitement des événements sur les composants par des procédures appelées écouteurs (listener) d’événement 5
6
PRINCIPES GÉNÉRAUX Organiser l’affichage des composants
On crée un container (JPanel ou autre) Si on ne souhaite pas utiliser le layout par défaut, on définit une mise en page des composants du container en lui associant un afficheur (LayoutManager = gestionnaire d’affichage) On ajoute ensuite les composants primitifs au container 6
7
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); }
8
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(); } }
9
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(); }
10
ARBRE DE COMPOSANTS L’ajout d’un composant à un composant (container) implique la construction d’un sous arbre - le composant ajouté est le fils Le parent contient les composants qui lui sont ajoutés La méthode getParent() sur un composant retourne le parent (de type Container) On a donc une arborescence des composants 10
11
Exemple : ARBRE DE COMPOSANTS
11
12
EXEMPLE D’APPLICATION JAVA SWING
JFrame frame = new JFrame("TopLevelDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create the menu bar. Make it have a green background. JMenuBar greenMenuBar = new JMenuBar(); greenMenuBar.setOpaque(true); /RVB greenMenuBar.setBackground(new Color(154, 165, 127)); greenMenuBar.setPreferredSize(new Dimension(200, 20)); //Create a yellow label to put in the content pane. JLabel yellowLabel = new JLabel(); yellowLabel.setOpaque(true); yellowLabel.setBackground(new Color(248, 213, 131)); yellowLabel.setPreferredSize(new Dimension(200, 180)); //Set the menu bar and add the label to the content pane. frame.setJMenuBar(greenMenuBar); frame.getContentPane().add(yellowLabel,BorderLayout.CENTER); 12
13
PARTIE 1 : LA VUE Principes généraux Hiérarchies des composants
Des Containers spécifiques La famille des panneaux Les autres composants Les afficheurs (Layout) Les Look’N’Feel Petits conseils 13
14
DES CONTAINERS SPÉCIFIQUES
JFrame : le cadre principal d'une application. Il peut contenir des menus et d'autres composants. JDialog : une fenêtre de dialogue avec l'utilisateur. Son « parent » (argument requis par ses créateurs) sert essentiellement à la placer dans l'écran. JApplet : classe de base pour les applets Java 2. Les applets sont des applications Java pouvant tourner à l'intérieur d'un navigateur Web. 14
15
JFRAME : ILLUSTRATION 15
16
JFRAME PAR L’EXEMPLE import javax.swing.*; public class TryWindow {
static JFrame myWindow = new JFrame (''ceci est un titre''); public static void main (String[] args) { myWindow.setBounds (50, 100, 400, 150); myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); myWindow.setVisible(true); } (0,0) x X=50 Y=100 W=400 H=150 y h 16 w
17
JFRAME PAR L’EXEMPLE setBounds définit la position et la taille
setVisible rend visible la fenêtre setDefaultCloseOperation détermine ce qu'il se passe lorsque l'on ferme la fenêtre (0,0) x DISPOSE_ON_CLOSE - détruit le JFrame et ses composants mais ne termine pas l'application DO_NOTHING_ON_CLOSE HIDE_ON_CLOSE y h 17 w
18
AUTRES MÉTHODES setTitle (String) : pour mettre le titre de la fenêtre
setSize (int width, int height) setLocation (int x, int y) : pour déplacer la fenêtre dispose () : pour fermer la fenêtre pack () : ajuste chaque composant à sa taille optimale et retaille la fenêtre 18
19
JDIALOG : CLASSES et BOÎTES DE DIALOGUES
Il existe différentes classes pour créer des boîtes de dialogue : JOptionPane : pour créer des boîtes de dialogue standards JColorChooser : pour choisir une couleur JFileChooser : pour permettre de sélectionner un fichier ProgressMonitor : pour afficher la progression d’une opération 19
21
JOPTIONPANE Permet de créer des boîtes de dialogue standards
Permet de faire des avertissements Possède des éléments standardisés : Réponse oui/non, Icônes de danger, d’erreurs, … Est modifiable (boutons, icônes, …) avertissement erreur information 21 question
22
JCOLORCHOOSER Permet de créer une boîte de dialogue pour choisir une couleur Possède différents onglets correspond aux différents types d’encodage de couleurs 22
23
JFILECHOOSER Définit une boîte de dialogue pour permettre sélectionner un fichier Possède des boîtes de dialogue par défaut : Pour l’ouverture (showOpenDialog), Pour la sauvegarde (showSaveDialog) 23
24
APPLET JAVA ÉTEND APPLET OU JAPPLET
S’exécute dans une machine virtuelle (celle du navigateur web) et nécessite un fichier html N’a pas de fonction main mais vit un cycle (run) Les principales méthodes sont : init () : quand la page html est chargée la 1ère fois start () : après init et chaque fois que l’on revient sur la page stop () : quand on quitte la page html (on interrompt les méthodes lancées dans start) destroy () : quand l’applet est terminée (on libère toutes les ressources) 24
25
EXEMPLE D’APPLET : CODE JAVA
import java.awt.*; Import java.applet.*; public class HelloWorldApplet extends Applet { Font f = new Font ( « Serif », Font.BOLD, 36); public void paint (Graphics g) { g.setFont(f); g.setColor(Color.red); g.drawString(getParameter (« Chaine »), 10, 30); } <HTML> <TITLE> Applet HelloWorldApplet </TITLE> <APPLET CODE=« HelloWorldApplet.class » WIDTH=200 HEIGHT=300> <PARAM NAME=« Chaine » value = « Hello World »> </APPLET> </HTML> 25
26
SÉCURITÉ ET APPLET Une applet ne peut pas charger de librairies ou utiliser des méthodes natives Elle ne peut normalement pas lire ou écrire dans des fichiers de l’hôte sur lequel elle s’exécute Elle ne peut pas effectuer de connexions réseaux sauf sur l’hôte dont elle provient Elle ne peut lancer aucun programme de l’hôte sur lequel elle s’exécute 26 Ces restrictions peuvent être levées par un certificat de sécurité (cf. jarsigner, policytool)
27
Hiérarchie de composants
28
HIÉRARCHIE DES CLASSES
28
29
Aperçu de Swing 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]
30
La famille des panneaux
30
31
TYPES DE PANNEAUX Pour structurer les différents éléments graphiques, on utilise des containers qui font partis de la famille des panneaux. On retrouve : Le JPanel : panneau de base, Le JScrollPane : qui permet d’obtenir des ascenseurs Le JSplitPane : qui permet de diviser en 2 (seulement 2) Le JTabbedPane : qui permet d’avoir différents onglets pour les différents sous-contenus 31
32
JPANEL Le container le plus utilisé pour structurer l’interface
Ne possède pas de réelles contraintes (la gestion de l’organisation des éléments est déléguée à un Layout) Peut contenir des sous-panneaux 32
33
JSCROLLPANE Permet d’obtenir des ascenseurs de manière automatique,
Est créé en lui associant le composant que l’on souhaite pouvoir scroller Le composant inclus dans le JScrollPane doit implémenter l’interface Scrollable Quelques éléments qui implémentent cette interface : JTextField, JTextArea, JTree, JTable 33
34
JSPLITPANE Permet de diviser en deux l’espace zone
Peut se construire avec les deux composants contenus dans chacune des zones Possède une orientation (HORIZONTAL_SPLIT ou VERTICAL_SPLIT) 34
35
JTABBEDPANE Permet d’avoir des onglets
Permet de mieux gérer l’espace de travail Chaque onglet est créé avec son panel associé L’onglet peut posséder une icône en plus ainsi qu’un raccourci clavier (Mnemonic) Peut-être fait de manière équivalente avec un CardLayout (à ce moment, il n’y a pas d’onglet) 35
36
LES DIFFÉRENTS PANNEAUX D’UN JFRAME, JDIALOG, JAPPLET
S’obtiennent par : getRootPane () zone de la fenêtre sous le titre getContentPane () zone où les éléments sont ajoutés getGlassPane () zone transparente dessinée au-dessus du JRootPane utilisé pour afficher des pop-up menus 36
37
Autres composants 37
38
LISTE NON EXHAUSTIVE DE COMPOSANTS SWING
JButton, JLabel, JTextField : une ligne de texte, JTextArea : une zone de texte, JCheckBox : boîte à cocher, JRadioButton : bouton pour sélection unique (associé à ButtonGroup), JMenu et JMenuItem : un menu et ses éléments (inclus dans une JMenuBar) JPopMenu : un menu flottant, JToolTip : une bulle d’aide, … 38
39
CRÉATION D’UN MENU Pour créer un menu, il faut :
Une barre de menu (JMenuBar), Un menu (JMenu), Des éléments dans ce menu (JMenuItem), Sur le menu, il est possible d’ajouter un Mnemonic Est associé à un caractère (setMnemonic(char)) Permet d’accéder au menu directement en faisant : Alt+Char Fonctionne également pour les boutons 39
40
CRÉATION D’UN MENU Sur les JMenuItem il est possible d’ajouter des accélérateurs : Permet d’associer une combinaison du type Ctrl+Touche Se définit pas : setAccelerator(KeyStroke.getKeyStroke ( KeyEvent.LA_TOUCHE, ActionEvent.LE_MASQUE) 40
41
ILLUSTRATION D’UN MENU
41
42
JLABEL Permet de définir un label
Peut comporter : une icône, du texte ou les deux ImageIcon ii = new ImageIcon(‘‘icon.jpg’’); Jlabel jl = new JLabel(‘‘text + icône’’, ii, JLabel.CENTER); 42
43
JLABEL Méthodes intéressantes :
setEnabled(boolean) : pour activer/désactiver la zone (permet de griser le label) setHorizontalAlignement(constante) pour contrôler l’alignement du texte 43
44
LES BORDURES Il est possible d’attribuer une bordure à un JComponent : setBorder(border) Pour obtenir la bordure, on utilise les méthodes statiques de la classe BorderFactory : Border Factory.createEtchedBorder() 44
45
Aperçu de Swing Des composants
JComponent Hérite de Container Méthodes de commodité getSize retourne une Dimension setSize : 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 –Les champs textuels –JTextField/ JTextArea Etc…
46
Exemple import javax.swing.*; import java.awt.*; public class FlowerPower { public static void main(String[] args) { JFrame fenetre = new JFrame(); JPanel panel = new JPanel(); JLabel etiquette = new JLabel("Aujourd'hui: "); JCheckBox premier = new JCheckBox("Lundi"); JCheckBox deuxieme = new JCheckBox("Mardi"); JCheckBox troisieme = new JCheckBox("Mercredi"); JCheckBox quatrieme = new JCheckBox("Jeudi"); JCheckBox cinquieme = new JCheckBox("Vendredi", true); JCheckBox sixieme = new JCheckBox("Samedi"); JCheckBox septieme = new JCheckBox("Dimanche");
47
Exemple panel.add(etiquette); panel.add(premier); panel.add(deuxieme); panel.add(troisieme); panel.add(quatrieme); panel.add(cinquieme); panel.add(sixieme); panel.add(septieme); fenetre.setContentPane(panel); fenetre.setTitle("Wesh mate mon flow!"); fenetre.setBounds(100,100,200,200); fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); fenetre.setVisible(true); } }
48
FlowLayout par défaut
49
Afficheurs 49
50
COMMENT POSITIONNER LES COMPOSANTS ?
50
51
DEUX MANIÈRES Positionner de manière absolue, revient à :
Retirer tout gestionnaire d’affichage (setLayout(null)) Placer un par un les éléments en leur donnant leur position dans la fenêtre (méthode setBounds) Positionner en utilisant des gestionnaires d’affichage 51
52
MISE EN PAGE DES COMPOSANTS
La mise en page des éléments s’effectue à l’aide d’un gestionnaire d’affichage (Layout), Tous les containers possèdent une méthode setLayout qui permet de spécifier le type de gestionnaire d’affichage On peut ajouter des contraintes lorsqu’on ajoute un composant 52
53
LES DIFFÉRENTS TYPE DE LAYOUT
BorderLayout, GridLayout, FlowLayout, CardLayout, BoxLayout, GridBagLayout 53
54
UTILISATION D’UN LAYOUT
Création du layout Exemple : BorderLayout bl = new BorderLayout()) 2. Association au container : panel.setLayout(bl) Ajout de composants au container, avec ou sans contrainte panel.add(button, BorderLayout. EAST) 54
55
BORDERLAYOUT Définit des zones dans lesquelles ajouter des éléments
Intéressant pour le panneau principal 55
56
GRIDLAYOUT Définit une grille où ajouter les composants
L’ajout des composants se fait sans préciser de contraintes On déclare le layout de la manière suivante : new GridLayout(0,2) // row, column 0 signifie autant qu’on veut 56
57
FLOWLAYOUT On ajoute au fur et à mesure les composants, si cela ne tient pas dans la ligne, on commence une nouvelle ligne Gestionnaire d’affichage par défaut des JPanel Possibilité de spécifier l’alignement 57
58
CARDLAYOUT Permet d’empiler des composants (suivant des panneaux)
CARDLAYOUT Permet d’empiler des composants (suivant des panneaux) Le dernier ajouté ou celui spécifié est visible Concept de la pile de cartes 58
59
BOXLAYOUT Définit une boîte dans laquelle seront ajoutés les différents composants Cette boîte peut-être : Horizontale : X_AXIS Verticale : Y_AXIS On ajoute les éléments au fur et à mesure 59
60
GRIDBAGLAYOUT (1/2) Gestionnaire d’affichage relativement compliqué à mettre en place Demande de définir toutes les contraintes des différents composants à placer Place les composants au-travers une grille modulaire 60
61
GRIDBAGLAYOUT (2/2) 61
62
Aperçu de Swing et 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.
63
Modèle & Vue
64
MODÈLE/VUE AVEC LES JLIST ET LES JTABLE
Il est possible de partager le modèle de données d’une JTable ou d’une JList à d’autres composants considérés comme d’autres vues de l’objet JTable ou JList Par exemple : une liste de noms affichée dans une JList. La JList est une vue (interactive) de la liste de noms permettant la sélection d’élément. Une représentation tabulaire de la même liste est une autre vue Un texte qui indique le nombre d’éléments de la liste est une autre vue du modèle 64
65
ILLUSTRATION 65
66
Définition du modèle associé
Si le modèle est décrit par une interface ListModel / TableModel prédéfinie, L’interface permet d’expliciter comment gérer les données du modèle et d’ajouter des vues (écouteurs de changements sur le modèle) Rem : il existe généralement une classe Adapter nommée Default<X>Model avec <X>=List ou Table Si le modèle change, il génère un événement et notifie les vues (via des méthodes en fire<…>) 66
67
Définition d’une nouvelle vue
Pour qu’un autre composant soit considéré comme une vue, il doit : Implémenter l’interface adéquate pour être écouteur de l’événement de changement de modèle Se faire ajouter à la liste des écouteurs du modèle 67
68
JLIST Possède différents constructeurs : Données fixes :
JList (Vector listData) JList (Object[] listData) Données modifiables : JList (ListModel dm) 68
69
JLIST Exemple String listData[]= {…,« Carlos »,…, « Ramier»};
DefaultListModel model = new DefaultListModel(); for (int i=0; i<listData.length; i++) model.addElement(listData[i]); JList dataList = new JList(model); JScrollPane listeScroll = new JScrollPane(dataList); 69
70
JLIST : LE MODÈLE ASSOCIÉ
Pour le modèle, utiliser la classe DefaultListModel. Ce modèle stocke les objets sous forme de vecteur et fournit les méthodes suivantes : addElement (Object), boolean contains(Object), boolean removeElement(Object) Object get(index), Object remove(index), int size() addListDataListener (ListDataListener l), remove… fireContentsChanged,fireIntervalAdded, fireIntervalRemoved (Object source, int index0, int index1) 70
71
ILLUSTRATION 71
72
JLIST Possède une méthode qui permet de spécifier le mode de sélection : setSelectionMode (int mode). mode peut valoir : SINGLE_SELECTION SINGLE_INTERVAL_SELECTION MULTIPLE_INTERVAL_SELECTION Possède une méthode addListSelectionListener () qui écoute un ListSelectionEvent e qui est émis à chaque fois qu’une sélection change et implémente une méthode : valueChanged 72
73
JLIST : LA VUE Une vue d’une JList implémente l’interface ListDataListener. Il y a trois méthodes : void contentsChanged(ListDataEvent e) : contenu de la liste a changé void intervalAdded(ListDataEvent e) void intervalRemoved(ListDataEvent e) l 73
74
JLIST : PLUSIEURS VUES ?! Créer un modèle instance de DefaultListModel et le mémoriser. Créer ensuite la liste avec ce modèle. Pour chaque composant désirant être informé des changements ( = d’autres vues ou le contrôleur) : Mémoriser le modèle ( = le stocker dans un membre) Implémenter ListDataListener Enregistrer le composant dans le modèle avec addListDataListener 74
75
JTABLE Un constructeur possible de JTable :
JTable (Object[][] rowData, Object[] columnNames) On peut accéder au modèle sous-jacent avec la méthode : TableModel getModel() Un autre constructeur avec directement le modèle : String nomsCol[]={«Prenom», «Nom»}; String rows[][] = { {«Dinah»,«Cohen»}, … , {«Said», «Kharrazen»}}; DefaultTableModel model = new DefaultTableModel(rows, nomsCol); JTable table = new JTable(model); 75
76
JTABLE : LE MODÈLE ASSOCIÉ
Il existe 3 différents éléments pour créer un modèle : L’interface TableModel La classe AbstractTableModel qui implémente TableModel La classe DefaultTableModel DefaultTableModel est le plus simple à utiliser, quelques constructeurs associés : DefaultTableModel(int row, int col) DefaultTableModel(Object[][] data, Object[] columnNames) DefaultTableModel(Vector data, Vector columnNames) … 76
77
JTABLE : LA VUE Une vue implémente l’interface TableDataListener
Il y a une méthode : void tableChanged(TableModelEvent e) L’événement associé TableModelEvent : int getType() : INSERT, UPDATE, DELETE int getColumn() int getFirstRow() int getLastRow() 77
78
JTABLE : PLUSIEURS VUES ?!
Créer un modèle, par exemple une instance de DefaultTableModel et le mémoriser Pour chaque composant désirant être informé des changements (les vues et/ou le contrôleur) : Mémoriser le modèle Implémenter TableModelListener Enregistrer le composant dans le modèle avec : addTableModelListener 78
79
SYNTHESE
80
Hiérarchie Swing
81
Aperçu de Swing swing_palettes.html Arch
82
Aperçu de Swing 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]
83
Aperçu de Swing Des composants
JComponent Hérite de Container Méthodes de commodité getSize retourne une Dimension setSize : 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/ JTextArea Etc…
84
Aperçu de Swing et 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.
85
Aperçu de Swing 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]
86
Exemple de code
87
EXEMPLE D’APPLICATION JAVA SWING
JFrame frame = new JFrame("TopLevelDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create the menu bar. Make it have a green background. JMenuBar greenMenuBar = new JMenuBar(); greenMenuBar.setOpaque(true); /RVB greenMenuBar.setBackground(new Color(154, 165, 127)); greenMenuBar.setPreferredSize(new Dimension(200, 20)); //Create a yellow label to put in the content pane. JLabel yellowLabel = new JLabel(); yellowLabel.setOpaque(true); yellowLabel.setBackground(new Color(248, 213, 131)); yellowLabel.setPreferredSize(new Dimension(200, 180)); //Set the menu bar and add the label to the content pane. frame.setJMenuBar(greenMenuBar); frame.getContentPane().add(yellowLabel,BorderLayout.CENTER); 87
88
Vous avez vu comment écrire la partie Modèle la partie Vue Reste comment mettre en place le contrôle ?
89
Observer Observable Rappel
90
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
91
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
92
Structure
93
Collaborations
94
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
95
Exemple de Listener jan.newmarch.name/java/replayJava/paper.htm
96
Listeners Supported by Swing Components
97
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); }
98
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(); } }
99
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(); }
100
Zoom sur les événements et les Listeners
LE CONTRÔLEUR Zoom sur les événements et les Listeners 100
101
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 101
102
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 102
103
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 103
104
HÉRITAGE DES EVÉNEMENTS
104
105
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 105
106
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 … 106
107
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. 107
108
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, … 108
109
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 109
110
LES ECOUTEURS Depuis (JAVA 1.1)
interfaces écouteurs correspondants aux masques d’événements principaux. extensions de java.util.EventListener. 110
111
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 111
112
Contrôle des Fenêtres WINDOWSLISTENER Concerne tout ce qui est en rapport avec la fenêtre : Ouvrir, Fermer, Réduire, Agrandir, … 112
113
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 113
114
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…. 114
115
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é 115
116
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é 116
117
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é 117
118
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 118
119
Contrôle du clavier KEYLISTENER, FOCUSLISTENER Concernent tout ce qui est en rapport avec le clavier : tapé pressé …. 119
120
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 120
121
FOCUSLISTENER focusGained(FocusEvent e) :
un composant obtient le focus focusLost(FocusEvent e) : un composant perd le focus 121
122
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 122
123
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 123
124
COMPONENTLISTENER componentHidden(ComponentEvent e) : le composant est rendu invisible componentShown(ComponentEvent e) : le composant est rendu visible 124
125
COMPONENTLISTENER componentMoved(ComponentEvent e) : la position du composant a changé componentResized(ComponentEvent e) : les dimensions du composant ont changé 125
126
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); 126
127
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 ) {}; 127
128
Quid de l’utilisation Il faut implémenter toutes les méthodes de l’interface, y compris celles dont on ne se sert pas……… 128
129
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 129
130
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 130
131
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 131
132
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 132
133
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) {} } 133 133
134
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 ... } 134
135
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); } 135
136
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 } }); 136
137
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 137
138
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 138
139
Ces trois événements sémantiques sont dans :
Hiérarchie Ces trois événements sémantiques sont dans : java.awt.event 139
140
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 140
141
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 141
142
EVÉNEMENTS ADJUSTMENTEVENT
Se produisent quand un élément ajustable comme une JScrollBar sont ajustés Sont émis par ScrollBar, JScrollBar 142
143
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) 143
144
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) 144
145
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…’’ 145
146
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 146 146
147
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); 147
148
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() 148
149
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) { }); 149
150
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 150
151
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); } 151
152
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); } 152
153
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 153
154
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 154
155
LES ACTIONS : PRINCIPE Les composants Swing suivants possèdent une méthode add() qui prend en argument un type Action : JMenu , JPopupMenu, JToolBar 155
156
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) 156
157
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. 157
158
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. 158
159
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) 159
160
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) 160
161
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) 161
162
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 162
163
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) 163
164
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 164
165
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); 165
166
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; } 166
167
Quid de l’insertion des Listeners
dans MVC Rappelez vous du premier Cours
168
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. 168
169
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; 169
170
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) 170
171
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; 171
172
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(); } 172
173
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())); 173
174
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 174
175
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(); 175
176
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 176
177
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 177
178
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); 178
179
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); 179
180
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 180
181
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); 181
182
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(); } 182
183
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())); 183
184
CONCLUSION 184
185
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 185
186
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 186
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.