Transparents swing
Upcoming SlideShare
Loading in...5
×
 

Transparents swing

on

  • 93 views

 

Statistics

Views

Total Views
93
Views on SlideShare
93
Embed Views
0

Actions

Likes
0
Downloads
1
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Transparents swing Transparents swing Document Transcript

  • Transparents Java, P.Durif 1 G´n´ralit´s e e e Programmation d’IHM avec Une IHM permet ` un ˆtre humain a e d’interagir avec un syst`me (informatique). e Java Swing Il y a trois aspects qu’il faut expliciter : – Le Mod`le est le syst`me manipul´ et doit e e e Philippe Durif conserver son autonomie (une BD par exemple) 13 novembre 2007 – La Vue (graphique ou textuelle) que donne l’IHM du Mod`lee – Le Contrˆle de ce que montre la vue ou de o l’´tat du mod`le via des boutons, menus ou des e e commandes textuelles propos´s par la vue. e Cela donne le classique mod`le MVC. e La chose la plus importante est probablement que le mod`le (M) soit compl`tement ind´pendant de e e e toutes IHM (VC) permettant de le manipuler. Dans ce cas il est possible d’avoir plusieurs IHM diff´rentes sur un mˆme mod`le. e e e Un administrateur syst`me pourra voir la liste des e comptes et y ajouter de nouveaux comptes, alors qu’un utilisateur ne pourra que l’observer. 0-0Transparents Java, P.Durif 2 Transparents Java, P.Durif 3 Exemples d’IHM Exemple d’IHM graphique IHM mat´rielle Distributeur de boissons e mod`le : l’eau, les produits lyophilis´s, la e e m´canique de production d’une boisson, e Sous Windows on a aussi plusieurs vues possibles ... du mˆme mod`le syst`me de fichiers : le Poste e e e de Travail et l’Explorateur Windows. vue : l’afficheur contrˆle : les boutons, la fente pour ins´rer o e les pi`ces de monnaie, . . . e Exp´rience : ouvrez simultan´ment un Poste de e e IHM informatique en mode texte Dans les Travail et un Explorateur Windows, puis environnements Unix on dispose g´n´ralement e e modifiez le mod`le via une de ces deux vues e de plusieurs vues sur le mod`le syst`me e e (cr´ez un r´pertoire par exemple). Miracle ! la e e Unix : sh, bash, csh, tcsh, ksh, . . . modification du mod`le est r´percut´e dans les e e e deux vues, ce qui montre bien l’unicit´ du mod`le. e e Qu’est-ce qui joue le rˆle de contrˆleur sous o o bash ?
  • Transparents Java, P.Durif 4 Transparents Java, P.Durif 5 Principe d’IHM Dispositifs d’IHM L’utilisateur ne per¸oit et n’agit sur le mod`le c e Physiques vue contrˆle o que par l’interm´diaire de la vue. e ´cran e X manette retour d’effort X Exemple o` le mod`le est une base de donn´es, u e e avec deux vues. clavier led X souris X ... decideur vue graphe vue liste administrateur Logiques vue contrˆle o bouton X X zone de texte X X modele ascenseur X X BDD label X ... Les fl`ches e indiquent la possibilit´ d’agir e Les dispositifs logiques sont g´n´ralement e e et de percevoir. d´sign´s de fa¸on g´n´rique par le mot widget e e c e e Les fl`ches e indiquent la possibilit´ de e (pour window gadget), Windows les appelle des percevoir. contrˆles et Swing des JComponent. oTransparents Java, P.Durif 6 Transparents Java, P.Durif 7 Les paquetages d’ihm du JDK AWT et Swing javax.swing nouvelle architecture AWT 1.0 : est obsol`te, traitement des e (JDK1.2) qui remplace partiellement AWT. ´v´nements effectu´e par les composants e e e graphiques eux-mˆmes. e java.awt les choses non obsol`tes : e AWT 1.1 : le traitement des ´v´nements est confi´ e e e – Container racine des widgets Swing, a des EventListener, les composants sont des ` – les gestionnaires de mise en page beans qui permettent de mettre en place des outils (LayoutManager), de programmation visuelle d’ihm. – la gestion des ´v´nements (AWTEvent). e e Swing 1.2 : versions am´lior´e des widgets AWT e e java.awt.event et javax.swing.event et nouveaux widgets, introduction du mod`lee pour les types ´v´nements et gestionnaires e e MVC, composants l´gers c’est a dire non associ´s e ` e d’´v´nements. e e a une fenˆtre native opaque, gestion du Look and ` e Pour ´viter les confusions entre les noms des e Feel. classes Swing at AWT, Swing ajoute un J en Swing n’est pas ind´pendant d’AWT. Par e d´but de nom. Par exemple JPanel de Swing est e exemple, Swing utilise l’architecture de traitement le successeur du Panel d’AWT. d’´v´nements (EventListener) et les e e gestionnaires de mise en page (LayoutManager) AWT est l’ancˆtre de Swing. e d’AWT.
  • Transparents Java, P.Durif 8 Transparents Java, P.Durif 9 Deux sortes de widgets Anatomie d’une IHM Java Il y a principalement deux sortes de widgets Une ihm est une hi´rarchie de widgets e widgets atomiques , ils disposent de : (Component) dont la racine est le JPanel de : – une repr´sentation graphique a l’´cran, e ` e – la possibilit´ de r´agir a des ´v´nements qui e e ` e e – une JFrame qui est la fenˆtre principale d’une e sont g´n´ralement cons´quences des actions e e e application de l’utilisateur, fournissant ainsi a ce ` – une JApplet destin´e a ˆtre t´l´charg´e et dont e `e ee e dernier la possibilit´ d’exprimer des e une instance sera ex´cut´e sur le poste client e e commandes. (par exemple, par un navigateur Web). Exemple : JButton, JLabel, JTextField et JList en Swing. Les nœuds internes sont des JPanel ou Box. widgets compos´s de sous-widgets e structurent le code et la pr´sentation visuelle : e Les feuilles sont des widgets atomiques. – hi´rarchie de widgets : JPanel et Box en e Swing, Exercice : tentez de dessiner la hi´rarchie d’une e – gestion de la mise en page graphique de ihm que vous utilisez. leurs widgets enfants grˆce aux a LayoutManager. Pour un exemple voir page 16.Transparents Java, P.Durif 10 Transparents Java, P.Durif 11 L’aspect visuel en Swing Hi´rarchie partielle de Swing e Tous les widgets Swing h´ritent de e java.awt.Container. – widgets atomiques : JButton , JTextField , JLabel , JList . java.awt Container LayoutManager – widgets compos´s : JPanel , e – JScrollPane : pour voir un widget trop grand dans une fenˆtre munie d’ascenseurs (un e JComponent JScrollPane JList ou un JTextArea par exemple). javax.swing – JFrame et JApplet : attention a bien utiliser ` getContentPane() pour ajouter des AbstractButton JTextComponent sous-widgets ou modifier le gestionnaire de mise en page, ou encore plus simple : setContentPane(). JButton JTextField – MenuElement : interface impl´ment´e par les e e diff´rents composants de menu : JMenuBar, e JFileChooser JList JPopupMenu, JMenu. Nouveau : les JFrame et les JApplet peuvent avoir une barre de menu JLabel Box JPanel (setJMenuBar()). Les LayoutManager d’AWT sont utilisables.
  • Transparents Java, P.Durif 12 Transparents Java, P.Durif 13 Principales m´thodes des widgets Swing e Gestionnaires de mise en page JButton (String text) Ce sont des classes qui implante l’interface addActionListener(ActionListener) LayoutManager et qui font la mise en page des removeActionListener(ActionListener) widgets d’un Container. JList voir plus loin page 39 Dans AWT : JTextField (int columns) – FlowLayout les widgets sont rang´se String getText (), setText (String) lin´airement de gauche a droite. e ` setEditable (boolean) – GridLayout une grille deux dimensions dont on fixe le nombre de lignes et de colonnes lors de JLabel (String/Icon) l’instanciation. String getText (), setText (String) – BorderLayout d´finit cinq zones que l’on e JFrame (String title) d´signe lors des ajouts de widget par la e setJMenuBar(JMenuBar mb) m´thode add avec les constantes e void setContentPane(Container) BorderLayout.NORTH, SOUTH, EAST, WEST, CENTER. Container getContentPane() Dans Swing : void pack (), void setVisible (boolean) – BoxLayout un peu comme FlowLayout mais JPanel (LayoutManager layout) peuvent ˆtre horizontaux ou verticaux. e Component add (Component comp) Il y en a bien d’autres !Transparents Java, P.Durif 14 Transparents Java, P.Durif 15 Exemples Exemple 1 : Coucou Avec les gestionnaires suivants : On veut manipuler le mod`le Compteur via une e JPanel p = new JPanel IHM : (new FlowLayout (FlowLayout.CENTER)) ; class Compteur { ou private int v = 0 ; public void incr () { v++;} JPanel p = new JPanel (new GridLayout (2, 4)); public int val () { return v; } ou } JPanel p = new JPanel () ; L’IHM doit permettre de : p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); 1. voir la valeur courante d’un Compteur (aspect la gestion de l’emplacement du prochain widget vue), ajout´ est implicite : e 2. d’incr´menter sa valeur (aspect contrˆle). e o p.add (new JTextField ()) ; p.add (new JButton ("Sauver")) ; Dans cette premi`re version on ne verra que la e Gestion explicite de l’emplacement du prochain partie MV de MVC. widget ajout´ : e JPanel p = new JPanel (new BorderLayout ()) ; p.add(new JTextField (), BorderLayout.CENTER); p.add(new JButton("Sauver"),BorderLayout.SOUTH);
  • Transparents Java, P.Durif 16 Transparents Java, P.Durif 17 Architecture de la vue coucou Exemple 1 : le main() La structure de la vue est une hi´rarchie stricte : e Dans un premier temps on ne g`re pas les e ´v´nements. e e un mˆme widget ne peut ˆtre affich´ a plus d’un e e e` endroit. L’application cr´e une fenˆtre (JFrame) dont le e e panel racine est IhmQuit : JFrame class AppliCoucou1 { setContentPane() public static void main (String arg []) { getContentPane() javax.swing.JFrame f = JPanel IhmQuit BorderLayout new javax.swing.JFrame ("Vue Coucou") ; f.setContentPane (new IhmQuit (new IhmCoucou(new Compteur ()))) ; JPanel IhmCoucou JButton f.pack () ; modele f.setVisible (true) ; } Compteur JButton JLabel }Transparents Java, P.Durif 18 Transparents Java, P.Durif 19 Exemple 1 : IhmQuit Exemple 1 : IhmCoucou class IhmCoucou extends javax.swing.JPanel { class IhmQuit private final Compteur c ; extends javax.swing.JPanel { private final javax.swing.JLabel l = new javax.swing.JLabel () ; public IhmQuit (javax.swing.JPanel jp) { // FlowLayout par defaut public IhmCoucou (Compteur c) { super (new java.awt.BorderLayout ()) ; // FlowLayout par defaut add (jp, java.awt.BorderLayout.CENTER) ; this.c = c ; javax.swing.JButton b = javax.swing.JButton b = new javax.swing.JButton ("Quitter") ; new javax.swing.JButton ("Coucou") ; add (b) ; add (b, java.awt.BorderLayout.SOUTH) ; add (l) ; } maj () ; } } private void maj () { Remarque : l.setText ("nombre de Coucous : " + c.val()) ; – IhmQuit accepte tout JPanel en param`tre, e } – on a choisi le LayoutManager BorderLayout. }
  • Transparents Java, P.Durif 20 Transparents Java, P.Durif 21 La gestion des ´v´nements e e Fonctionnement g´n´ral e e C’est le C de MVC. 1. suite a une action de l’utilisateur sur un ` widget, ce widget g´n`re un ´v´nement e e e e AWTEvent . Exemples : ActionEvent, Elle permet de programmer ce qui doit ˆtre fait e WindowEvent, KeyEvent, MouseEvent en r´ponse aux actions de l’utilisateur. e 2. ensuite, le widget fait traiter une copie de cet ´v´nement par chacun des listeners e e Elle est identique en AWT 1.1 et en Swing avec EventListener qui lui sont connect´s et qui e quelques types d’´v´n´ments suppl´mentaires e e e e sont capables de traiter ce type d’´v´nement. e e pour Swing. Par exemple, un ActionListener traitera uniquement les ActionEvent et un WindowListener les WindowEvent. Plus La gestion des ´v´nements se programme en e e g´n´ralement, un XxxListener traite e e implantant les interfaces listener souhait´es, puis e uniquement les XxxEvent. en en connectant des instances aux diff´rents e widgets. Le traitement d’un ´v´nement est fait en appelant e e une des m´thodes du listener correspondant. eTransparents Java, P.Durif 22 Transparents Java, P.Durif 23 Un sch´ma e Architecture partielle Event/Listener Voici dans quel ordre se d´roulent les choses : e Il y a une bijection entre les types d’´v´nement et e e les types de listener d´finis par le JDK. e 1 widget 2 event HAUT NIVEAU AWTEvent action mes listeners 4/3 clone 3/4 ActionListener TextListener ItemListener ActionEvent TextEvent ItemEvent listener listener listener 1 2 3 BAS NIVEAU ComponentEvent mes listeners WindowListener widget InputEvent WindowEvent KeyListener MouseListener abstrait On remarque qu’un mˆme listener peut ˆtre e e KeyEvent MouseEvent concret connect´ a plusieurs widgets. e` interface Les listeners sont d´clench´s dans un seul thread, e e donc de fa¸on s´quentielle. En revanche on ne sait c e ´ e Ev´nements de haut niveau → application. pas dans quel ordre ils seront d´clench´s. e e ´ e Ev´nements de bas niveau → Swing/AWT.
  • Transparents Java, P.Durif 24 Transparents Java, P.Durif 25 Listener ` une seule m´thode a e Listener ` plus d’une m´thode a e Par exemple le listener ActionListener dispose Un listener peut proposer plus d’une m´thode e de l’unique m´thode : e pour traiter un ´v´nement. e e actionPerformed (ActionEvent evt) C’est cette m´thode qui sera appel´e lorsque le e e Le choix de la m´thode appel´e d´pend alors de la e e e widget auquel est connect´ le listener g´n´rera un e e e nature pr´cise de l’´v´nement. e e e ActionEvent. Voici un ActionListener permettant de quitter l’application : Par exemple, int´ressons-nous a un widget auquel e ` class Quitter implements est connect´ un KeyListener : e java.awt.event.ActionListener { 1. quand on enfonce la touche a du clavier, les public void actionPerformed m´thodes keyPressed() puis keyTyped() e (java.awt.event.ActionEvent event) { sont appel´es, e // D’abord sauver le mod`le, puis : e 2. quand on relˆche la touche, c’est a System.exit (0) ; keyReleased() qui est appel´e. e } }Transparents Java, P.Durif 26 Transparents Java, P.Durif 27 Les adapters Quelques m´thodes d’´v´nement e e e Pour la plupart des listeners qui ont plus d’une Pour ´crire le code d’une m´thode de listener il e e m´thode, le JDK fournit une impl´mentation par e e est parfois insuffisant de connaˆ le type ıtre d´faut dont les m´thodes ne font rien. On appelle e e d’´v´nement. On peut alors interroger e e ces classes des adapters. Par exemple, l’´v´nement lui-mˆme pour obtenir des e e e KeyListener dispose de l’adapter KeyAdapter et informations. WindowListener de l’adapter WindowAdapter. Voici par exemple les informations qu’on peut Ces adapters facilitent la vie du programmeur, obtenir aupr`s de tout ´v´nement (AWTEvent) et e e e mais l’expose a des erreurs de programmation ` aupr`s d’un ´v´nement souris (MouseEvent) : e e e difficiles a localiser. ` AWTEvent Une erreur typique consiste a surcharger une ` getSource() renvoie le Component qui a m´thode d´finie par l’adapter au lieu de la e e g´n´r´ cet ´v´nement e ee e e red´finir car on s’est tromp´ sur le type du e e MouseEvent param`tre formel (l’exemple d’erreur classique est e getX(), getY() position relative a getSource() ` de surcharger la m´thode equals au lieu de la e isPopupTrigger() touche de droite sous Linux red´finir). e Une autre erreur consiste a mal orthographier le ` nom de la m´thode cens´e ˆtre red´finie. e e e e £   ¢Solution : L’annotation @Override de Java5 ¡
  • Transparents Java, P.Durif 28 Transparents Java, P.Durif 29 Connexion d’un listener Exemple de Connexion On connecte un listener a un widget quand on ` Pour que le bouton quitter permette de quitter veut que quelque chose se passe quand ce widget l’application, on impl´mente l’interface e g´n`re un ´v´nement. e e e e ActionListener par la classe Quitter et on en connecte une instance au bouton avec la m´thode e Pour connecter un listener de type Xxx a un ` addActionListener() : widget, on utilise la m´thode addXxxListener() e de ce dernier. class Quitter implements Il y a une bijection entre les types d’´v´nements, e e java.awt.event.ActionListener { les listeners et les m´thodes de connexion, par e public void actionPerformed exemple : (java.awt.event.ActionEvent event) { // D’abord sauver le mod`le, puis : e ´v´nement e e listener m´thode de e System.out.println ("See you soon") ; connexion System.exit (0) ; ActionEvent ActionListener addActionListener() } WindowEvent WindowListener addWindowListener() } KeyEvent KeyListener addKeyListener() MouseEvent MouseListener addMouseListener() JButton b = new JButton ("Quitter") ; et plus g´n´ralement e e b.addActionListener (new Quitter ()) ; XxxEvent XxxListener addXxxListener()Transparents Java, P.Durif 30 Transparents Java, P.Durif 31 Quels ´v´nements pour quels e e Exemple 2 widget ? Reprenons l’application de l’exemple 1 pour y Tous les widgets ne g´n`rent pas forc´ment tous e e e int´grer la gestion d’´v´nements : e e e les ´v´nements possibles. e e class AppliCoucou2 { public static void main (String arg []) { javax.swing.JFrame f = new javax.swing.JFrame ("Vue Coucou"); Un widget sait g´n´rer et traiter un ´v´nement e e e e final Quitter quit = XxxEvent s’il dispose directement ou par h´ritage e new controleur.Quitter () ; de la m´thode addXxxListener(). e f.addWindowListener (quit) ; f.setContentPane (new IhmQuit (new IhmCoucou(new Compteur()), quit)); f.pack () ; // ou f.setSize (250, 100) ; Exercice : retrouver tous les ´v´nements qu’un e e f.setVisible (true) ; JButton sait g´n´rer. e e } } On remarque que le constructeur IhmQuit() est maintenant param´tr´ par un Quitter. e e
  • Transparents Java, P.Durif 32 Transparents Java, P.Durif 33 Exemple 2 : le listener Quitter Exemple 2 : IhmQuit Le mˆme listener permet de quitter l’application e soit via les menus de la fenˆtre, soit via un e class IhmQuit extends javax.swing.JPanel { bouton. Il impl´mente donc les deux interfaces : e public IhmQuit (javax.swing.JPanel jp, package controleur ; controleur.Quitter quit) public class Quitter { extends java.awt.event.WindowAdapter super (new java.awt.BorderLayout ()) ; implements java.awt.event.ActionListener { add (jp, java.awt.BorderLayout.CENTER) ; @Override public void windowClosing (java.awt.event.WindowEvent w) { javax.swing.JButton b = System.exit (0) ; new javax.swing.JButton ("Quitter") ; } b.addActionListener (quit) ; public void actionPerformed add (b, java.awt.BorderLayout.SOUTH) ; (java.awt.event.ActionEvent e) { } System.exit (0) ; } } } Remarque : le mˆme listener Quitter est e Noter l’extension de l’adapter WindowAdapter et connect´ sur la JFrame et sur le JButton. e l’utilisation de l’annotation @Override.Transparents Java, P.Durif 34 Transparents Java, P.Durif 35 Exemple 2 : IhmCoucou Conception Technique On suppose les import effectu´s e class IhmCoucou extends JPanel { Le mod`le devrait ˆtre un objet observable e e private final Compteur c ; (java.util.Observable) et la vue un private final JLabel l = new JLabel () ; public IhmCoucou (Compteur c) { observateur du mod`le (java.util.Observer). e this.c = c ; Un observer sera averti des changements d’´tat du e JButton b = new JButton ("Coucou") ; mod`le et pourra ainsi mettre a jour son e ` b.addActionListener affichage, ainsi les modifications faites via une (new controleur.Incr (this, c)) ; IHM seront visibles dans toutes les autres IHM add (b) ; add (l) ; maj () ; } observant le mˆme mod`le. e e private void maj () { l.setText ("nombre de Coucous : " + c.val()); L’IHM devrait ˆtre une sous-classe de JPanel e } } } dont le constructeur est param´tr´ par une e e package controleur ; instance du mod`le. e public class Incr implements ActionListener { private IhmCoucou vue ; private Compteur c ; public Incr (IhmCoucou vue, Compteur c) { En principe, pour la JFrame (ou la JApplet) il this.vue = vue ; this.c = c ; n’y a plus qu’` fixer son panel racine, h´riter de a e } JFrame ne paraˆ pas indispensable. ıt public void actionPerformed (ActionEvent e) { c.incr () ; vue.maj () ; } }
  • Transparents Java, P.Durif 36 Transparents Java, P.Durif 37 Les menus Exemple de barre de menu Swing En AWT les ´l´ments de menu n’´taient pas des ee e widgets (ou Component) ! File Edit Heureusement, en Swing, l’architecture des menus JMenuBar est int´gr´e dans la hi´rarchie JComponent : e e e Charger Couper JComponent Sauver Copier JMenuItem JMenu Coller MenuElement AbstractButton Options JMenu n n JMenuBar JPopupMenu JMenuItem JMenu JFrame ou JApplet n JMenu La m´thode setJMenuBar (JMenuBar) permet de e fixer la barre de menu d’une JFrame et d’une Fig. 1 – Hi´rarchie des MenuElement : JMenuBar, e JApplet. JMenu et JPopupMenu sont des conteneurs. JMenu permet de cr´er des menus hi´rarchiques. e eTransparents Java, P.Durif 38 Transparents Java, P.Durif 39 Le widget liste Liste Swing :JList L’avantage d´terminant des JList est qu’elles e Rˆle d’une liste : pr´senter sous forme synth´tique o e e int`grent le mod`le dans leur fonctionnement, ce e e une liste d’´l´ments du mod`le (par exemple des ee e qui all`ge ´norm´ment le travail du programmeur e e e fontes de caract`res, des ´tudiants, des fichiers, e e (par rapport aux List d’AWT). ...) dans laquelle on peut choisir un ou plusieurs Le widget JList Swing est param´trable par : e ´l´ments. ee – ListModel le mod`le qui stocke les ´l´ments e ee visualis´s dans la JList. Ces ´l´ments peuvent e ee La repr´sentation graphique de chaque ´l´ment e ee ˆtre de n’importe quel type r´f´rence. Lorsque e ee (chaˆ de caract`res, image, . . .) doit permettre ıne e ce mod`le est modifi´ (ajout, suppression ou e e d’identifier de fa¸on non ambigu¨ chacun des c e modification d’´l´ments), il doit en informer la ee ´l´ments du mod`le. ee e JList en appelant une des m´thodes e fireXxx(). La modification de la visualisation La probl´matique principale li´e a l’utilisation de e e ` de la liste sera alors faite automatiquement. liste est la mise en correspondance entre les En Java5, ListModel et JList ne sont pas ´l´ments du mod`le et leurs ee e g´n´riques ! e e repr´sentations graphiques : quand un e – ListCellRenderer l’objet qui impl´mente la e utilisateur clique sur une repr´sentation e mani`re d’afficher chaque ´l´ment du e ee graphique, ce n’est pas cette derni`re qu’il veut e ListModel. manipuler, mais l’´l´ment qu’elle identifie. ee – ListSelectionModel l’objet qui stocke l’´tat e courant de la s´lection dans la JList. e
  • Transparents Java, P.Durif 40 Transparents Java, P.Durif 41 Architecture des JList Swing Personnalisation d’une JList Personnaliser le ListModel (indispensable) : n 1. sp´cialiser la classe AbstractListModel pour e ListDataListener cr´er un nouveau ListModel, e AbstractListModel DefaultListCellRenderer 2. utiliser le constructeur JList(ListModel) ou la m´thode setModel(). e Personnaliser le ListCellRenderer (pas rare) : ListModel ListCellRenderer 1. sp´cialiser DefaultListCellRenderer pour e 1 1 adapter son comportement. Ce dernier utilise la m´thode toString() des objets du e JList ListModel pour les visualiser. 1 2. utiliser la m´thode setCellRenderer() de la e ListSelectionModel JList. Personnaliser le ListSelectionModel (rare) : 1. le d´faut semble convenir la plupart du e DefaultListSelectionModel temps, mais on peut sp´cialiser e n DefaultListSelectionModel ListSelectionListener 2. utiliser la m´thode setSelectionModel() de e la JList.Transparents Java, P.Durif 42 Transparents Java, P.Durif 43 Personnalisation d’une JList Changements d’´tats du mod`le e e Les ListDataListener connect´s au mod`le e e (addListDataListener()) lui permettent de signaler ses changements d’´tat. e interface ListDataListener { void intervalAdded(ListDataEvent e) ; void intervalRemoved(ListDataEvent e) ; Enfin, au niveau de la JList on peut utiliser void contentsChanged(ListDataEvent e) ; } setSelectionMode(int) pour obtenir un des trois comportement suivant : AbstractListModel propose trois m´thodes void e pour d´clencher ces listeners : e SINGLE_SELECTION un ´l´ment s´lectionn´ au ee e e fireIntervalAdded (Object src, int x0, int x1) plus fireIntervalRemoved(Object src, int x0, int x1) SINGLE_INTERVAL_SELECTION un intervalle fireContentsChanged(Object src, int x0, int x1) d’´l´ments s´lectionn´s au plus ee e e src est le ListModel et x0, x1 les indices de la zone. MULTIPLE_INTERVAL_SELECTION plusieurs x0=5, x1=11 ⇒ intervalle [5, 11] intervalles d’´l´ments s´lectionn´s ee e e Attention : x0=5, x1=4 ⇒ intervalle [4, 5] non vide $ Une JList attache automatiquement des ListDataListener a son mod`le, ce qui garan- ` e tit que la ou les vues JList seront toujours a jour. ` & % JList int`gre le mod`le observateur/observ´. e e e
  • Transparents Java, P.Durif 44 Transparents Java, P.Durif 45 Attention Contrˆle de la s´lection o e Plusieurs listeners du mˆme type peuvent ˆtre e e Les ListSelectionListener connect´s au e connect´s a un mˆme objet source. e ` e ListSelectionModel ou a la JList seront ` appel´s a chaque fois que l’utilisateur modifie la e ` Quand l’´v´nement correspondant a ces listeners e e ` s´lection de la JList. e est produit par l’objet source, ils sont tous ex´cut´s. e e interface ListSelectionListener { void valueChanged (ListSelectionEvent e) ; Java garantit que ces listeners seront ex´cut´s e e } dans un seul thread, c’est a dire s´quentiellement. ` e L’´v´nement ListSelectionEvent ne donne pas e e En revanche on ne sait rien de l’ordre dans d’information pr´cise sur le nouvel ´tat de la e e lequel ces listeners seront ex´cut´s. e e s´lection : le listener devra interroger l’´metteur e e Autrement dit, si le bon fonctionnement de l’un de cet ´v´nement ou bien simplement la JList e e de ces listeners d´pend du fait qu’un autre de ces e avec par exemple : listener ait d´j` ´t´ ex´cut´, on peut dire que eaee e e l’application contient une erreur. public int getMinSelectionIndex ()   Si vous connectez vos propres ListDataListener public int[] getSelectedIndices () a votre mod`le, prenez bien garde qu’ils ne ` e public Object getSelectedValue () public Object[] getSelectedValues ()   d´pendent pas de l’´tat de la JList ! ! ! e eTransparents Java, P.Durif 46 Transparents Java, P.Durif 47 Exemple : liste d’´tudiant e Le mod`le promotion (ListModel) e class Promotion extends AbstractListModel { Supposons qu’on veuille afficher une promotion private java.util.List<Etudiant> l = d’Etudiant new java.util.ArrayList<Etudiant> () ; public Etudiant get (int i) { return l.get (i) ; } // Pour l’interface ListModel public int getSize () { return l.size () ; } interface Etudiant { public Object getElementAt (int index) { public String nom () ; return get (index) ; } public int moyenne () ; // M´thodes sp´cifiques du mod`le e e e public void ajouter (int note) ; public void ajouter (Etudiant e) { } final int index = l.size () ; l.add (e) ; fireIntervalAdded (this, index, index) ; // Appelle la m´thode intervalAdded() de e // chacun des ListDataListener connect´s e // a ce ListModel. ` } }
  • Transparents Java, P.Durif 48 Transparents Java, P.Durif 49 La JList sur une promotion Diagramme d’une instance de JList Etudiant class JList_Etudiant extends Les objets listener sont dans un double cadre : javax.swing.JList { public JList_Etudiant (Promotion p) { super (p) ; setCellRenderer(new EtudiantRenderer()) ; DoubleClic setSelectionMode (javax.swing. ListSelectionModel.SINGLE_SELECTION) ; Promotion EtudiantRenderer getSelectionModel() .addListSelectionListener (new NouvelleSelection ()) ; JList_Etudiant this.addMouseListener (new DoubleClic (this)) ; DefaultListSelectionModel } } NouvelleSelectionTransparents Java, P.Durif 50 Transparents Java, P.Durif 51 Le ListCellRenderer d’´tudiant e Le contrˆleur NouvelleSelection o class EtudiantRenderer extends En principe on ne devrait pas avoir a ´crire un tel `e javax.swing.DefaultListCellRenderer { listener : une interface classique pr´sente d’une e part la liste et d’autre part des boutons public java.awt.Component permettant chacun d’effectuer une action sur les getListCellRendererComponent ´l´ments actuellement s´lectionn´s, par exemple : ee e e (javax.swing.JList list, ´diter, supprimer, . . . e Object value, int index, boolean isSelected, On imprime un message a chaque changement de ` boolean cellHasFocus) { s´lection effectu´e par l’utilisateur : e e Etudiant e = (Etudiant) value ; return super.getListCellRendererComponent class NouvelleSelection implements (list, javax.swing.event.ListSelectionListener { e.nom () + ": " + e.moyenne (), public void valueChanged index, (javax.swing.event.ListSelectionEvent e) { isSelected, if (! e.getValueIsAdjusting()) { cellHasFocus System.out.println("S´lection modifi´e"); e e ) ; } } } } }
  • Transparents Java, P.Durif 52 Transparents Java, P.Durif 53 Le contrˆleur DoubleClic o Inhibition des widgets On veut qu’un double clic avec le bouton gauche de la Une bonne IHM doit guider l’utilisateur : en souris provoque l’impression dans la console de particulier si certaines actions n’ont pas de sens a ` l’´l´ment de liste ainsi s´lectionn´ : ee e e un moment donn´, on doit pouvoir empˆcher e e class DoubleClic l’utilisateur de s’en servir. extends java.awt.event.MouseAdapter { private JList_Etudiant l ; public DoubleClic (JList_Etudiant l) { Par exemple, si sous xemacs, le fichier ´dit´ n’a e e this.l = l ; } pas ´t´ modifi´ depuis sa derni`re sauvegarde ee e e @Override public void mouseClicked alors l’action Save du menu File est inhib´e. e (java.awt.event.MouseEvent e) { if ((e.getModifiers() == java.awt.event.InputEvent.BUTTON1_MASK Regardez vos IHM pr´f´r´es pour voir si elles ont eee ) && e.getClickCount() == 2) { ce comportement. final int I=l.locationToIndex(e.getPoint()); if (I != - 1) System.out.println (((Promotion) l.getModel()).get(I).nom()); AWT et donc Swing permettent cette inhibition } } } avec la m´thode setEnabled(boolean) e disponible sur tous les widgets. On remarque avec quelle facilit´ on retrouve l’´tudiant e e concern´ par le double-clic (locationToIndex()). eTransparents Java, P.Durif 54 Transparents Java, P.Durif 55 Notion de focus clavier focus clavier et JDK 1.4 Le widget qui a le focus (ou point de mire) est celui qui recevra tous les ´v´nements clavier, e e mˆme s’il n’est pas sous la souris. e Le JDK 1.4 d´finit un fonctionnement par d´faut e e du focus qui devrait ˆtre satisfaisant dans la e Au plus un widget, parmi toutes les fenˆtres de e plupart des cas, il est cependant possible de le l’application, peut avoir le focus a un moment ` personnaliser simplement grˆce aux m´thodes : a e donn´. e Container.setFocusTraversalKeys() Container.getFocusTraversalPolicy() ContainerOrderFocusTraversalPolicy. En g´n´ral on d´place le focus sur un autre widget e e e setImplicitDownCycleTraversal(boolean) – soit par un clic de la souris, – soit avec la touche tabulation avant pour avancer sur le prochain widget. – soit avec la touche tabulation arri`re pour e Une personnalisation plus pouss´e peut-ˆtre e e reculer sur le widget pr´c´dent. e e obtenue au prix d’une bonne compr´hension du e m´canisme de gestion du focus. e Une bonne gestion du focus est certainement un ´l´ment d´terminant de l’ergonomie d’une IHM. ee e
  • Transparents Java, P.Durif 56 Transparents Java, P.Durif 57 javax.swing.Action javax.swing.JScrollPane C’est une sp´cialisation de ActionListener tr`s e e On peut mettre un widget, trop grand pour ˆtre e pratique quand on veut : compl`tement visible, dans un JScrollPane. e – qu’un mˆme listener avec le mˆme intitul´ soit e e e accessible de plusieurs mani`res dans l’IHM, e – pouvoir d´sactiver/r´activer ce listener de fa¸on e e c centralis´e (m´thode setEnabled(boolean)). e e On dispose alors d’ascenseurs verticaux et On peut ajouter une mˆme Action dans un e horizontaux permettant de faire d´filer le widget. e JMenu, un JPopupMenu ou une JToolBar avec add(Action). Ceci cr´era automatiquement le JMenuItem ou le e JButton correspondant. Exemple : JScrollPane scroll = new JScrollPane (new JList_Etudiant (...)) ; La classe javax.swing.AbstractAction est une impl´mentation de Action qui peut facilement e ˆtre ´tendue. e eTransparents Java, P.Durif 58 Transparents Java, P.Durif 59 javax.swing.JDialog Modalit´ du JDialog e Comme son nom l’indique, un JDialog est une En modal (comportement s´quentiel de e fenˆtre secondaire permettant a l’utilisateur de e ` l’utilisateur), n´cessaire quand la r´ponse au e e saisir des donn´es, r´pondre a une question, . . .. e e ` dialogue est indispensable a la suite du ` d´roulement de l’application. Il faut : cr´er le e e dialogue en indiquant qu’il est modal ensuite, a ` chaque fois qu’on rend visible le dialogue, Un JDialog d´pend toujours d’une fenˆtre qu’on e e l’application principale est bloqu´e jusqu’` ce que e a appelle son propri´taire (owner). e le dialogue soit rendu invisible (voir la m´thode e setVisible(boolean) h´rit´e de e e java.awt.Component). Le JDialog subira les mˆmes actions que sa e fenˆtre propri´taire, par exemple, si le propri´taire e e e En non modal (comportement parall`le dee est iconis´, le JDialog disparaˆ e ıtra pour l’utilisateur), quand le dialogue contient toujours r´apparaˆ d`s que son propri´taire sera agrandi. e ıtre e e une valeur que le programme principal peut consulter a tout moment (par exemple le dialogue ` de choix de la couleur du crayon dans un logiciel de dessin est souvent non modal) La sp´cificit´ primordiale d’un JDialog est d’ˆtre e e e ou non modal. Un JFileChooser est un dialogue tout prˆt pour e s´lectionner un fichier. e void setFileFilter (FileFilter filter)
  • Transparents Java, P.Durif 60 Transparents Java, P.Durif 61 Composition du JDialog Programmation bas niveau Pour composer un JDialog on peut utiliser, Comment un widget est dessin´ e comme pour les JFrame et les JApplet : En AWT, c’est la m´thode paint(Graphics) qui e fait tout le travail. – sa m´thode getContentPane() qui renvoie son e En Swing, la m´thode publique paint(Graphics) e panel racine, on peut ensuite y mettre ce que appelle successivement les trois m´thodes e l’on veut. protected : 1. paintComponent (Graphics) 2. paintBorder (Graphics) 3. paintChildren (Graphics) – sa m´thode setContentPane() pour fixer e brutalement son panel racine. Pour modifier l’apparence d’un widget Swing, il suffit d’en h´riter et de red´finir la m´thode e e e paintComponent (Graphics).Transparents Java, P.Durif 62 Transparents Java, P.Durif 63 java.awt.Graphics Application : BoutonCroix Tout widget dispose d’un contexte graphique On veut un bouton qui affiche une croix quand il mat´rialis´ par un objet de type Graphics. e e est enfonc´. Pour cela on h´rite de JButton et on e e red´finit paintComponent() : e import java.awt.* ; On peut demander son Graphics a un widget ` class BX extends javax.swing.JButton { avec la m´thode : getGraphics(). e public BX (String text) { super (text) ; } protected void paintComponent (Graphics g) { if (getModel ().isPressed ()) { Un Graphics contient les informations de base Rectangle R = g.getClipBounds(); permettant le dessin du widget a l’´cran : l’origine ` e Point O = R.getLocation() ; de la zone de dessin, sa fenˆtre de d´coupage e e g.clearRect(O.x, O.y, R.width, R.height); (clipping), la couleur du crayon, la fonte de g.drawLine(O.x, O.y, caract`res, . . . e O.x+R.width, O.y+R.height); g.drawLine(O.x, O.y+R.height, O.x+R.width, O.y); Quelques m´thodes de Graphics : drawLine(), e } else { drawString(), setColor(), . . . super.paintComponent (g) ; } } }