Vous êtes sur la page 1sur 78

Forums Tutoriels Magazine FAQs Blogs Projets Chat Newsletter tudes Emploi Club Contacts

Accueil ALM Java .NET Dv. Web EDI Langages

SGBD Office Solutions d'entreprise Applications Mobiles Systmes


Java

Spring Dv. Web Java Android Eclipse NetBeans

FORUMS JAVA

FAQs JAVA

TUTORIELS JAVA

JAVASEARCH

SOURCES

LIVRES

OUTILS, EDI & API

BLOG

DISCUSSIONS

TV

Dveloppons en Java
Copyright (C) 1999-2013 Jean-Michel DOUDOUX

1.90 (date de publication : 25/02/2013)

[ Prcdent ] [ Sommaire ] [ Suivant ] [Tlcharger ]

[Accueil ]

16. Le dveloppement d'interfaces graphiques avec SWING

Niveau :

Intermdiaire

Swing fait partie de la bibliothque Java Foundation Classes (JFC). C'est une API dont le but est similaire celui de l'API AWT mais dont les modes de fonctionnement et d'utilisation sont compltement diffrents. Swing a t intgr au JDK depuis sa version 1.2. Cette bibliothque existe sparment. pour le JDK 1.1.

La bibliothque JFC contient :

l'API Swing : de nouvelles classes et interfaces pour construire des interfaces Accessibility API : 2D API: support du graphisme en 2D API pour l'impression et le cliquer/glisser
Ce chapitre contient plusieurs sections : graphiques

La prsentation de Swing Les packages Swing Un exemple de fentre autonome Les composants Swing Les boutons Les composants de saisie de texte Les onglets Le composant JTree Les menus L'affichage d'une image dans une application.

16.1. La prsentation de Swing


Swing propose de nombreux composants dont certains possdent des fonctions tendues, une utilisation des mcanismes de gestion d'vnements performants (ceux introduits par le JDK 1.1) et une apparence modifiable la vole (une interface graphique qui emploie le style du systme d'exploitation Windows ou Motif ou un nouveau style spcifique Java nomm Metal). Tous les lments de Swing font partie d'un package qui a chang plusieurs fois de nom : le nom du package dpend de la version du J.D.K. utilise :

com.sun.java.swing : jusqu' la version 1.1 beta 2 de Swing, de la version 1.1 des java.awt.swing : utilis par le J.D.K. 1.2 beta 2 et 3 javax.swing : partir des versions de Swing 1.1 beta 3 et J.D.K. 1.2 RC1
Les composants Swing forment un nouvelle hirarchie parallle celle de l'AWT. L'anctre de cette hirarchie est le composant JComponent. Presque tous ses composants sont crits en pur Java : ils ne possdent aucune partie native sauf ceux qui assurent l'interface avec le systme d'exploitation : JApplet, JDialog, JFrame, et JWindow. Cela permet aux composants de toujours avoir la mme apparence quelque soit le systme sur lequel l'application s'excute. Tous les composants Swing possdent les caractristiques suivantes : JFC et de la version 1.2 beta 4 du J.D.K.

ce sont des beans ce sont des composants lgers (pas de partie native) hormis quelques exceptions. leurs bords peuvent tre changs
La procdure suivre pour utiliser un composant Swing est identique celle des composants de la bibliothque AWT : crer le composant en appelant son constructeur, appeler les mthodes du composant si ncessaire pour le personnaliser et l'ajouter dans un conteneur. Swing utilise la mme infrastructure de classes qu'AWT, ce qui permet de mlanger des composants Swing et AWT dans la mme interface. Il est toutefois recommand

d'viter de les utiliser simultanment car certains peuvent ne pas tre restitus correctement. Les composants Swing utilisent des modles pour contenir leurs tats ou leurs donnes. Ces modles sont des classes particulires qui possdent toutes un comportement par dfaut.

16.2. Les packages Swing


Swing contient plusieurs packages : package principal : il contient les interfaces, les principaux composants, les modles par dfaut Classes reprsentant les bordures Classes dfinissant un composant pour la slection de couleurs Classes et interfaces pour les vnements spcifiques Swing. Les autres vnements sont ceux d'AWT (java.awt.event) Classes dfinissant un composant pour la slection de fichiers Classes et l'apparence interfaces gnriques pour grer

javax.swing javax.swing.border javax.swing.colorchooser

javax.swing.event

javax.swing.filechooser javax.swing.plaf javax.swing.plaf.basic javax.swing.plaf.metal javax.swing.table javax.swing.text javax.swing.text.html javax.swing.text.html.parser javax.swing.text.rtf javax.swing.tree javax.swing.undo

Classes et interfaces de base pour grer l'apparence Classes et interfaces pour dfinir l'apparence Metal qui est l'apparence par dfaut Classes dfinissant un composant pour prsentation de donnes sous forme de tableau la

Classes et interfaces de bases pour les composants manipulant du texte Classes permettant le support du format HTML Classes permettant d'analyser des donnes au format HTML Classes permettant le support du format RTF Classes dfinissant un composant pour prsentation de donnes sous forme d'arbre Classes permettant annuler/refaire d'implmenter les la

fonctions

16.3. Un exemple de fentre autonome


La classe de base d'une application est la classe JFrame. Son rle est quivalent la classe Frame de l'AWT et elle s'utilise de la mme faon.

*;

tends JFrame {

l'application");

= new WindowAdapter() { indowClosing(WindowEvent e){ t(0);

r(l); ; ;

main(String [] args){ ew swing1();

16.4. Les composants Swing


Il existe des composants Swing quivalents pour chacun des composants AWT avec des constructeurs semblables. De nombreux constructeurs acceptent comme argument un objet de type Icon, qui reprsente une petite image gnralement stocke au format Gif. Le constructeur d'un objet Icon admet comme seul paramtre le nom ou l'URL d'un fichier graphique

*;

tends JFrame {

'application");

= new WindowAdapter() { indowClosing(WindowEvent e){ t(0);

r(l);

new ImageIcon("tips.gif"); new JButton("Mon bouton",img); new JPanel();

on); anneau); ; ;

ain(String [] args){ ew swing3();

16.4.1. La classe JFrame JFrame est l'quivalent de la classe Frame de l'AWT : les principales diffrences sont l'utilisation du double buffering qui amliore les rafraichissements et l'utilisation d'un panneau de contenu (contentPane) pour insrer des composants (ils ne sont plus insrs sans le JFrame mais dans l'objet contentPane qui lui est associ). Elle reprsente une fentre principale qui possde un titre, une taille modifiable et ventuellement un menu. La classe possde plusieurs constructeurs : Constructeur JFrame() JFrame(String) Cration d'une instance en prcisant le titre Rle

Par dfaut, la fentre cre n'est pas visible. La mthode setVisible() permet de l'afficher.

e1 {

ain(String argv[]) { ame("ma fenetre"); ; ;

La gestion des vnements est identique celle utilise dans l'AWT depuis le J.D.K. 1.1.

*;

tends JFrame {

'application");

= new WindowAdapter() { indowClosing(WindowEvent e){ (0);

(l);

new JButton("Mon bouton"); new JPanel(); n);

nneau);

main(String [] args){ ew swing2();

Tous les composants associs un objet JFrame sont grs par un objet de la classe JRootPane. Un objet JRootPane contient plusieurs Panes. Tous les composants ajouts au JFame doivent tre ajouts un des Pane du JRootPane et non au JFrame directement. C'est aussi un de ces Panes qu'il faut associer un layout manager si ncessaire.

Le Pane le plus utilis est le ContentPane. Le Layout manager par dfaut du contentPane est BorderLayout. Il est possible de le changer :

Layout(new FlowLayout());

e2 {

ain(String argv[]) {

ame("ma fenetre");

; tton("Mon bouton"); .add(b); ;

Le JRootPane se compose de plusieurs lments :

glassPane : un JPanel par dfaut layeredPane qui se compose du contentPane (un JPanel par dfaut) et du menuBar
(un objet de type JMenuBar) Le glassPane est un JPanel transparent qui se situe au-dessus du layeredPane. Le glassPane peut tre n'importe quel composant : pour le modifier il faut utiliser la mthode setGlassPane() en fournissant le composant en paramtre. Le layeredPane regroupe le contentPane et le menuBar. Le contentPane est par dfaut un JPanel opaque dont le gestionnaire de prsentation est un BorderLayout. Ce panel peut tre remplac par n'importe quel composant grce la mthode setContentPane().

Attention : il ne faut pas utiliser directement la mthode setLayout() d'un objet JFrame sinon une exception est leve.

e7 {

ain(String argv[]) {

ame("ma fenetre"); owLayout()); ; ;

tJFrame7 ain" java.lang.Error: Do not use javax.swing.JFrame.setLay JFrame.getContentPane().setLayout() instead .JFrame.createRootPaneException(Unknown Source) .JFrame.setLayout(Unknown Source) .main(TestJFrame7.java:8) Le menuBar permet d'attacher un menu la JFrame. Par dfaut, le menuBar est vide. La mthode setJMenuBar() permet d'affecter un menu la JFrame.

tion d'un menu trs simple

e6 {

ain(String argv[]) {

ame("ma fenetre"); ; tton("Mon bouton"); .add(b);

new JMenuBar(); Bar);

Menu("Fichier"); ;

16.4.1.1. Le comportement par dfaut la fermeture Il est possible de prciser comment un objet JFrame, JInternalFrame, ou JDialog ragit sa fermeture grce la mthode setDefaultCloseOperation(). Cette mthode attend en paramtre une valeur qui peut tre : Constante WindowConstants.DISPOSE_ON_CLOSE WindowConstants.DO_NOTHING_ON_CLOSE WindowConstants.HIDE_ON_CLOSE Rle dtruit la fentre rend le bouton de fermeture inactif cache la fentre

Cette mthode ne permet pas d'associer d'autres traitements. Dans ce cas, il faut intercepter l'vnement et lui associer les traitements.

ntre disparat lors de sa fermeture mais l'application ne se termine pas.

e3 {

ain(String argv[]) {

ame("ma fenetre"); ; tton("Mon bouton"); .add(b);

peration(WindowConstants.DISPOSE_ON_CLOSE);

16.4.1.2. La personnalisation de l'icne La mthode setIconImage() permet de modifier l'icne de la JFrame.

e4 {

ain(String argv[]) {

ame("ma fenetre"); ; tton("Mon bouton"); .add(b); peration(WindowConstants.DISPOSE_ON_CLOSE);

new ImageIcon("book.gif"); ge.getImage()); ;

Si l'image n'est pas trouve, alors l'icne est vide. Si l'image est trop grande, elle est redimensionne.

16.4.1.3. Centrer une JFrame l'cran Par dfaut, une JFrame est affiche dans le coin suprieur gauche de l'cran. Pour la centrer dans l'cran, il faut procder comme pour une Frame : dterminer la position de la Frame en fonction de sa dimension et de celle de l'cran et utiliser la mthode setLocation() pour affecter cette position.

e5 {

ain(String argv[]) {

ame("ma fenetre"); ; tton("Mon bouton"); .add(b);

peration(WindowConstants.DISPOSE_ON_CLOSE);

olkit.getDefaultToolkit().getScreenSize(); width/2 - f.getWidth()/2, dim.height/2 - f.getHeight()/2);

16.4.1.4. Les vnements associes un JFrame La gestion des vnements associs un objet JFrame est identique celle utilise pour un objet de type Frame de AWT.

*;

e8 {

ain(String argv[]) {

ame("ma fenetre"); ; ; r(new WindowAdapter() { ndowClosing(WindowEvent e) { 0);

16.4.2. Les tiquettes : la classe JLabel Le composant JLabel propose les mmes fonctionnalits que les intituls AWT mais ils peuvent en plus contenir des icnes . Cette classe possde plusieurs constructeurs : Constructeurs JLabel() JLabel(Icon) JLabel(Icon, int) JLabel(String) JLabel(String, int) Icon, Rle Cration d'une instance sans texte ni image Cration d'une instance en prcisant l'image Cration d'une instance en prcisant l'image et l'alignement horizontal Cration d'une instance en prcisant le texte Cration d'une instance en prcisant le texte, l'image et l'alignement horizontal Cration d'une instance en prcisant le texte et l'alignement

JLabel(String, int)

horizontal

Le composant JLabel permet d'afficher un texte et/ou une icne en prcisant leur alignement. L'icne doit tre au format GIF et peut tre une animation dans ce format.

l1 {

ain(String argv[]) {

ame("ma fenetre"); ;

w JPanel(); w JLabel("Mon texte dans JLabel"); );

new ImageIcon("book.gif"); w JLabel(icone); );

w JLabel("Mon texte",icone,SwingConstants.LEFT); );

.add(pannel); ;

La classe JLabel dfinit plusieurs mthodes pour modifier l'apparence du composant : Mthodes setText() setOpaque() setBackground() setFont() setForeGround() setHorizontalAlignment() setVerticalAlignment() setHorizontalTextAlignment() Rle Permet d'initialiser ou de modifier le texte affich Indique si le composant est transparent (paramtre false) ou opaque (true) Indique la couleur de fond du composant (setOpaque doit tre true) Permet de prciser la police du texte Permet de prciser la couleur du texte Permet de modifier l'alignement horizontal du texte et de l'icne Permet de modifier l'alignement vertical du texte et de l'icne Permet de modifier l'alignement horizontal du texte uniquement Permet de modifier l'alignement vertical du texte uniquement setVerticalTextAlignment() Exemple :

jLabel.setVerticalTextPosition(SwingConstants.TOP); setIcon() setDisabledIcon() Permet d'assigner une icne Permet de dfinir l'icne associe au JLabel lorsqu'il est dsactiv

L'alignement vertical par dfaut d'un JLabel est centr. L'alignement horizontal par dfaut est soit droite s'il ne contient que du texte, soit centr s'il contient une image avec ou sans texte. Pour modifier cet alignement, il suffit d'utiliser les mthodes cidessus en utilisant des constantes en paramtres : SwingConstants.LEFT, SwingConstants.CENTER, SwingConstants.RIGHT, SwingConstants.TOP, SwingConstants.BOTTOM Par dfaut, un JLabel est transparent : son fond n'est pas dessin. Pour le dessiner, il faut utiliser la mthode setOpaque() :

l2 {

ain(String argv[]) {

ame("ma fenetre");

; w JPanel();

w JLabel("Mon texte dans JLabel 1"); und(Color.red); );

w JLabel("Mon texte dans JLabel 2"); und(Color.red); true); );

.add(pannel); ;

Dans l'exemple, les 2 JLabel ont le fond rouge demand par la mthode setBackground(). Seul le deuxime affiche un fond rouge car il est rendu opaque avec la mthode setOpaque(). Il est possible d'associer un raccourci clavier au JLabel qui permet de donner le focus un autre composant. La mthode setDisplayedMnemonic() permet de dfinir le raccourci clavier. Celui-ci sera activ en utilisant la touche Alt avec le caractre fourni en paramtre. La mthode setLabelFor() permet d'associer le composant fourni en paramtre au raccourci.

l3 {

ain(String argv[]) {

ame("ma fenetre"); ; w JPanel();

ew JButton("saisir"); ; new JTextField("votre nom");

w JLabel("Nom : "); und(Color.red); edMnemonic('n'); r(jEdit); );

.add(pannel); ;

Dans l'exemple, l'ouverture de la fentre, le focus est sur le bouton. Un appui sur Alt+'n' donne le focus au champ de saisie.

16.4.3. Les panneaux : la classe JPanel La classe JPanel est un conteneur utilis pour regrouper et organiser des composants grce un gestionnaire de prsentation (layout manager). Le gestionnaire par dfaut d'un JPanel est un objet de la classe FlowLayout.

16.5. Les boutons


Il existe plusieurs boutons dfinis par Swing.

16.5.1. La classe AbstractButton C'est une classe abstraite dont hritent les boutons Swing JButton, JMenuItem et JToggleButton. Cette classe dfinit de nombreuses mthodes dont les principales sont : Mthode AddActionListener AddChangeListener AddItemListener doClick() getText() setDisabledIcon() setDisabledSelectedIcon() setEnabled() setMnemonic() setPressedIcon() setRolloverIcon() setRolloverSelectedIcon() setSelectedIcon() setText() isSelected() setSelected() Rle Associer un couteur sur un vnement de type ActionEvent Associer un couteur sur un vnement de type ChangeEvent Associer un couteur sur un vnement de type ItemEvent Dclencher un clic par programmation Obtenir le texte affich par le composant Associer une icne affiche lorsque le composant a l'tat dslectionn Associer une icne affiche lors du passage de la souris sur le composant l'tat dslectionn Activer/dsactiver le composant Associer un raccourci clavier Associer une icne affiche lorsque le composant est cliqu Associer une icne affiche lors du passage de la souris sur le composant Associer une icne affiche lors du passage de la souris sur le composant l'tat slectionn Associer une icne affiche lorsque le composant a l'tat slectionn Mettre jour le texte du composant Indiquer si le composant est dans l'tat slectionn Dfinir l'tat du composant (slectionn ou non selon la valeur fournie en paramtre

Tous les boutons peuvent afficher du texte et/ou une image. Il est possible de prciser une image diffrente lors du passage de la souris sur le composant et lors de l'enfoncement du bouton : dans ce cas, il faut crer trois images pour chacun des tats (normal, enfonc et survol). L'image normale est associe au bouton grce au constructeur, l'image enfonce grce la mthode setPressedIcon() et l'image lors d'un survol grce la mthode setRolloverIcon(). Il suffit enfin d'appeler la mthode setRolloverEnable() avec en paramtre la valeur true.

*;

tends JFrame {

'application");

= new WindowAdapter() { dowClosing(WindowEvent e){ );

(l);

rmale = new ImageIcon("arrow.gif"); ssage = new ImageIcon("arrowr.gif"); foncee = new ImageIcon("arrowy.gif");

new JButton("Mon bouton",imageNormale); Icon(imageEnfoncee); rIcon(imagePassage); rEnabled(true); add(bouton, "Center");

new JPanel(); n); nneau);

main(String [] args){ ew swing4();

Un bouton peut recevoir des vnements de type ActionEvents (le bouton a t activ), ChangeEvents, et ItemEvents.

eture de l'application lors de l'activation du bouton

*;

on3 {

ain(String argv[]) {

ame("ma fenetre"); ; w JPanel();

new JButton("Bouton1"); istener( new ActionListener() { ionPerformed(ActionEvent e) { );

); .add(pannel); ;

Pour de plus amples informations sur la gestion des vnements, voir le chapitre correspondant.

16.5.2. La classe JButton JButton est un composant qui reprsente un bouton : il peut contenir un texte et/ou une icne. Les constructeurs sont :

Constructeur

Rle

JButton()

JButton(String)

prciser le texte du bouton

JButton(Icon)

prciser une icne

JButton(String, Icon)

prciser un texte et une icne

Il ne gre pas d'tat. Toutes les indications concernant le contenu du composant JLabel sont valables pour le composant JButton.

outon avec une image

*;

tends JFrame {

l'application");

= new WindowAdapter() { indowClosing(WindowEvent e){ t(0);

r(l);

new ImageIcon("tips.gif"); new JButton("Mon bouton",img);

new JPanel(); on); anneau); ; ;

ain(String [] args){ ew swing3();

L'image gif peut tre une animation. Dans un conteneur de type JRootPane, il est possible de dfinir un bouton par dfaut grce sa mthode setDefaultButton().

nition d'un bouton par dfaut dans un JFrame

on2 {

ain(String argv[]) {

ame("ma fenetre"); ; w JPanel(); new JButton("Bouton 1"); );

new JButton("Bouton 2"); );

new JButton("Bouton 3"); );

.add(pannel); tDefaultButton(bouton3); ;

Le bouton par dfaut est activ par un appui sur la touche Entre alors que le bouton actif est activ par un appui sur la barre d'espace. La mthode isDefaultButton() de JButton permet de savoir si le composant est le bouton par dfaut.

16.5.3. La classe JToggleButton Cette classe dfinit un bouton deux tats : c'est la classe mre des composants JCheckBox et JRadioButton.

La mthode setSelected() hrite de AbstractButton permet de mettre jour l'tat du bouton. La mthode isSelected() permet de connatre cet tat.

16.5.4. La classe ButtonGroup La classe ButtonGroup permet de grer un ensemble de boutons en garantissant qu'un seul bouton du groupe sera slectionn. Pour utiliser la classe ButtonGroup, il suffit d'instancier un objet et d'ajouter des boutons (objets hritant de la classe AbstractButton) grce la mthode add(). Il est prfrable d'utiliser des objets de la classe JToggleButton ou d'une de ses classes filles car elles sont capables de grer leurs tats.

Button1 {

ain(String argv[]) {

ame("ma fenetre"); ; w JPanel(); new ButtonGroup(); = new JRadioButton("Bouton 1");

= n1 ); ); n2 ); ); n3 ); );

= new JRadioButton("Bouton 2");

= new JRadioButton("Bouton 3");

.add(pannel); ;

16.5.5. Les cases cocher : la classe JCheckBox Les constructeurs sont les suivants : Constructeur JCheckBox(String) JCheckBox(String, boolean) JCheckBox(Icon) JCheckBox(Icon, boolean) JCheckBox(String, Icon) Rle prcise l'intitul prcise l'intitul et l'tat spcifie l'icne utilise prcise l'intitul et l'tat du bouton prcise l'intitul et l'icne

JCheckBox(String, Icon, boolean)

prcise l'intitul, une icne et l'tat

Un groupe de cases cocher peut tre dfini avec la classe ButtonGroup. Dans ce cas, un seul composant du groupe peut tre slectionn. Pour l'utiliser, il faut crer un objet de la classe ButtonGroup et utiliser la mthode add() pour ajouter un composant au groupe.

kBox1 {

ain(String argv[]) {

ame("ma fenetre"); ; w JPanel();

= new JCheckBox("Bouton 1"); ); = new JCheckBox("Bouton 2"); ); = new JCheckBox("Bouton 3"); );

.add(pannel); ;

16.5.6. Les boutons radio : la classe JRadioButton Un objet de type JRadioButton reprsente un bouton radio d'un groupe de boutons dans lequel un seul peut tre slectionn. La classe JRadioButton hrite de la classe AbstractButton. Un bouton radio possde un libell et ventuellement une icne pour chacun des tats du bouton qui peut tre prcise en utilisant les mthodes setIcon(), setSelectedIcon() et setPressedIcon().

oButton1 {

ain(String argv[]) {

ame("ma fenetre"); ; w JPanel(); n1 = new JRadioButton("Bouton 1"); ); n2 = new JRadioButton("Bouton 2"); ); n3 = new JRadioButton("Bouton 3");

);

.add(pannel); ;

La mthode isSelected() permet de savoir si le bouton est slectionn ou non. La classe JRadioButton possde plusieurs constructeurs : Constructeur JRadioButton() JRadioButton(Icon) JRadioButton(Icon, boolean) JRadioButton(String) JRadioButton(String, boolean) JRadioButton(String, Icon) JRadioButton(String, boolean) Icon, Rle Crer un bouton non slectionn sans libell Crer un bouton non slectionn sans libell avec l'icne fournie en paramtre Crer un bouton sans libell avec l'icne et l'tat fourni en paramtre Crer un bouton non slectionn avec le libell fourni en paramtre Crer un bouton avec le libell et l'tat fournis en paramtre Crer un bouton non slectionn avec le libell et l'icne fournis en paramtre Crer un bouton avec le libell, l'icne et l'tat fournis en paramtre

Un groupe de bouton radio est encapsul dans un objet de type ButtonGroup. Il faut ajouter tous les JRadioButton du groupe en utilisant la mthode add() de la classe ButtonGroup. Lors de la slection d'un bouton, c'est l'objet de type ButtonGroup qui se charge de dselectionner le bouton prcdemment slectionn dans le groupe. Un groupe n'a pas d'obligation d'avoir un bouton slectionn.

Layout; ner; yout; derFactory; tonGroup; ame; nel; dioButton; der.Border;

oButton extends JFrame { ain(String args[]) { pp = new TestJRadioButton();

t radio boutons");

seOperation(JFrame.EXIT_ON_CLOSE); JPanel(new GridLayout(0,1)); rderFactory.createTitledBorder("Slection"); rder); = new ButtonGroup(); 1 = new JRadioButton("Choix 1", true); 2 = new JRadioButton("Choix 2"); 3 = new JRadioButton("Choix 3");

ane = this.getContentPane(); nel, BorderLayout.CENTER); 150); ue);

Layout; ner; yout; KeyEvent; derFactory; tonGroup; ame; nel; dioButton; der.Border;

oButton extends JFrame { ain(String args[]) { pp = new TestJRadioButton();

t radio boutons"); seOperation(JFrame.EXIT_ON_CLOSE); JPanel(new GridLayout(0, 1)); rderFactory.createTitledBorder("Slection"); rder); = new ButtonGroup(); 1 = new JRadioButton("Choix 1"); (KeyEvent.VK_1);

mmand("Choix_1"); (true);

2 = new JRadioButton("Choix 2"); (KeyEvent.VK_2);

mmand("Choix_2"); 3 = new JRadioButton("Choix 3"); (KeyEvent.VK_3);

mmand("Choix_3");

ane = this.getContentPane(); nel, BorderLayout.CENTER); 150); ue);

Lors de la slection d'un bouton du groupe, il y a plusieurs vnements qui peuvent tre mis :

Un vnement de type Action Un vnement de type Item mis par le bouton slectionn Un vnement de type Item mis par le bouton dslectionn s'il y en a un

Layout; ner; yout; ActionEvent; ActionListener; ItemEvent; ItemListener; KeyEvent; derFactory; tonGroup; ame; nel; dioButton; der.Border;

oButton extends JFrame implements ActionListener, ItemListener { ain(String args[]) { pp = new TestJRadioButton();

t radio boutons");

seOperation(JFrame.EXIT_ON_CLOSE); JPanel(new GridLayout(0, 1)); rderFactory.createTitledBorder("Slection"); rder); = new ButtonGroup(); 1 = new JRadioButton("Choix 1"); (KeyEvent.VK_1);

mmand("Choix_1"); (true); 2 = new JRadioButton("Choix 2"); (KeyEvent.VK_2);

mmand("Choix_2"); 3 = new JRadioButton("Choix 3"); (KeyEvent.VK_3);

mmand("Choix_3");

stener(this); stener(this); stener(this); ener(this); ener(this); ener(this); ane = this.getContentPane(); nel, BorderLayout.CENTER); 150); ue);

rformed(ActionEvent e) { ("Clic sur le bouton : " + e.getActionCommand());

eChanged(ItemEvent e) { Bouton " + ((JRadioButton) e.getItem()).getActionCommand()); ge() == ItemEvent.DESELECTED) ln(" deselectionne"); ge() == ItemEvent.SELECTED) ln(" selectionne");

La mthode getSelection() de la classe ButtonGroup renvoie le modle du bouton radio slectionn encapsul dans un objet de type ButtonModel. Pour dterminer le bouton slectionner, il faut parcourir les boutons du groupe et comparer leur modle avec celui slectionn.

Button getBoutonSelectionne(ButtonGroup group) { t = null;

= group.getElements(); e.hasMoreElements();) { ton = (JRadioButton) e.nextElement(); del() == group.getSelection()) { n;

16.6. Les composants de saisie de texte


Swing possde plusieurs composants pour permettre la saisie de texte.

16.6.1. La classe JTextComponent La classe abstraite JTextComponent est la classe mre de tous les composants permettant la saisie de texte. Les donnes du composant (le modle dans le motif de conception MVC) sont encapsules dans un objet qui implmente l'interface Document. Deux classes implmentant cette interface sont fournies en standard : PlainDocument pour du texte simple et StyledDocument pour du texte riche pouvant contenir entre autre plusieurs polices de caractres, des couleurs, des images, ... La classe JTextComponent possde de nombreuses mthodes dont les principales sont :

Mthode

Rle

void copy()

Copier le contenu du texte et le mettre dans le presse papier systme

void cut()

Couper le contenu du texte et le mettre dans le presse papier systme

Document getDocument()

Renvoyer l'objet de type Document qui encapsule le texte saisi

String getSelectectedText()

Renvoyer le texte slectionn dans le composant

int getSelectionEnd()

Renvoyer la position de la fin de la slection

int getSelectionStart()

Renvoyer la position du dbut de la slection

String getText()

Renvoyer le texte saisi

String getText(int, int)

Renvoyer une portion du texte dbutant partir de la position donne par le premier paramtre et la longueur donne dans le second paramtre

bool isEditable()

Renvoyer un boolen qui prcise si le texte est ditable ou non

void paste()

Coller le contenu du presse papier systme dans le composant

void select(int,int)

Slectionner une portion du texte dont les positions de dbut et de fin sont fournies en paramtres

void setCaretPosition(int)

Dplacer le curseur dans le texte la position prcis en paramtre

void setEditable(boolean)

Permet de prciser si les donnes du composant sont ditables ou non

void setSelectionEnd(int)

Modifier la position de la fin de la slection

void setSelectionStart(int)

Modifier la position du dbut de la slection

void setText(String)

Modifier le contenu du texte

Toutes ces mthodes sont donc accessibles grce l'hritage pour tous les composants de saisie de texte proposs par Swing.

16.6.2. La classe JTextField La classe javax.Swing.JTextField est un composant qui permet la saisie d'une seule ligne de texte simple. Son modle utilise un objet de type PlainDocument.

d1 {

ain(String argv[]) {

ame("ma fenetre"); ); w JPanel();

eld1 = new JTextField ("mon texte");

ld1); .add(pannel); ;

La proprit horizontalAligment permet de prciser l'alignement du texte dans le composant en utilisant les valeurs JTextField.LEFT , JTextField.CENTER ou JTextField.RIGHT.

16.6.3. La classe JPasswordField La classe JPasswordField permet la saisie d'un texte dont tous les caractres saisis seront affichs sous la forme d'un caractre particulier ('*' par dfaut). Cette classe hrite de la classe JTextField.

ion;

Field1 {

ain(String argv[]) {

ame("ma fenetre"); ); w JPanel();

sswordField1 = new JPasswordField (""); PreferredSize(new Dimension(100,20 ));

dField1); .add(pannel); ;

La mthode setEchoChar(char) permet de prciser le caractre qui sera montr lors de la saisie. Il ne faut pas utiliser la mthode getText() qui est dclare deprecated mais la mthode getPassword() pour obtenir la valeur du texte saisi.

ion; *;

Field2 implements ActionListener {

ordField1 = null;

ain(String argv[]) { f2 = new JPasswordField2();

ame("ma fenetre");

); w JPanel();

ew JPasswordField(""); PreferredSize(new Dimension(100, 20)); dField1);

new JButton("Afficher"); istener(this);

); .add(pannel); ;

rformed(ActionEvent e) {

("texte saisie = " + String.copyValueOf(passwordField1.getPassword()));

Les mthodes copy() et cut() sont redfinies pour n'mettre qu'un bip. Elles empchent l'exportation du contenu du champ.

16.6.4. La classe JFormattedTextField Le JDK 1.4 propose la classe JFormattedTextField pour faciliter la cration d'un composant de saisie personnalis. Cette classe hrite de la classe JTextField.

16.6.5. La classe JEditorPane Ce composant permet la saisie de texte riche multilignes. Ce type de texte peut contenir des informations de mise en pages et de formatage. En standard, Swing propose le support des formats RTF et HTML.

hage de la page de Google avec gestion des hyperliens

nt.*;

ne1 {

ain(String[] args) { editeur; w JPanel();

ditorPane(new URL("http://google.fr")); ble(false); linkListener(new HyperlinkListener() { perlinkUpdate(HyperlinkEvent e) { ntType() == HyperlinkEvent.EventType.ACTIVATED) { e.getURL(); null)

setPage(e.getURL()); xception ex) { StackTrace();

ur); e1) { ce();

ame("ma fenetre"); );

.add(pannel); ;

16.6.6. La classe JTextPane

La suite de cette section sera dveloppe dans une version future de ce document

16.6.7. La classe JTextArea La classe JTextArea est un composant qui permet la saisie de texte simple en mode multiligne. Le modle utilis par ce composant est le PlainDocument : il ne peut donc contenir que du texte brut sans lments multiples de formatage. JTexteArea propose plusieurs mthodes pour ajouter du texte dans son modle :

soit fournir le texte en paramtre du constructeur utilis soit utiliser la mthode setText() qui permet d'initialiser le texte du composant soit utiliser la mthode append() qui permet d'ajouter du texte la fin de celui
contenu dans le composant

soit utiliser la mthode insert() qui permet d'insrer du texte dans le composant
une position donnes en caractres La mthode replaceRange() permet de remplacer la partie de texte occupant les index donns en paramtres par la chane fournie. La proprit rows permet de dfinir le nombre de lignes affiches par le composant : cette proprit peut donc tre modifie lors d'un redimensionnement du composant. La proprit lineCount en lecture seule permet de savoir le nombre de lignes qui composent le texte. Il ne faut pas confondre ces deux proprits.

1 {

ain(String argv[]) {

ame("ma fenetre"); ); w JPanel();

a1 = new JTextArea ("mon texte");

a1); .add(pannel); ;

Par dfaut, la taille du composant augmente au fur et mesure de l'augmentation de la taille du texte qu'il contient. Pour viter cet effet, il faut encapsuler le JTextArea dans un JScrollPane.

ion;

1 {

ain(String argv[]) {

ame("ma fenetre"); ); w JPanel(); a1 = new JTextArea ("mon texte"); Pane = new JScrollPane(textArea1); erredSize(new Dimension(200,70)); ane); .add(pannel); ;

16.7. Les onglets


La classe javax.swing.JTabbedPane encapsule un ensemble d'onglets. Chaque onglet est constitu d'un titre, d'un composant et ventuellement d'une image. Pour utiliser ce composant, il faut :

instancier un objet de type JTabbedPane crer le composant de chaque onglet ajouter chaque onglet l'objet JTabbedPane en utilisant la mthode addTab()

ion; KeyEvent;

edPane1 {

ain(String[] args) { ame("Test JTabbedPane"); ); w JPanel();

s = new JTabbedPane(SwingConstants.TOP);

ew JPanel(); 1 = new JLabel("Onglet 1"); nglet1); edSize(new Dimension(300, 80)); glet1", onglet1);

ew JPanel(); 2 = new JLabel("Onglet 2"); nglet2); glet2", onglet2);

true); ); .add(pannel); ;

A partir du JDK 1.4, il est possible d'ajouter un raccourci clavier sur chacun des onglets en utilisant la mthode setMnemonicAt(). Cette mthode attend deux paramtres : l'index de l'onglet concern (le premier commence 0) et la touche du clavier associe sous la forme d'une constance KeyEvent.VK_xxx. Pour utiliser ce raccourci, il suffit d'utiliser la touche dsigne en paramtre de la mthode avec la touche Alt. La classe JTabbedPane possde plusieurs mthodes qui permettent de dfinir le contenu de l'onglet :

Mthodes

Rles

addTab(String,

Permet d'ajouter un nouvel onglet dont le titre et le composant sont fournis en paramtres. Cette mthode possde plusieurs surcharges

Component)

qui permettent de prciser une icne et une bulle d'aide

insertTab(String, Icon, Permet d'insrer un onglet dont la position est prcise dans le Component, String, index) dernier paramtre

remove(int)

Permet de supprimer l'onglet dont l'index est fourni en paramtre

setTabPlacement

Permet de prciser le positionnement des onglets dans le composant JTabbedPane. Les valeurs possibles sont les constantes TOP, BOTTOM, LEFT et RIGHT dfinies dans la classe JTabbedPane.

La mthode getSelectedIndex() permet d'obtenir l'index de l'onglet courant. La mthode setSelectedIndex() permet de dfinir l'onglet courant.

16.8. Le composant JTree


Le composant JTree permet de prsenter des donnes sous une forme hirarchique arborescente.

Au premier abord, le composant JTree peut sembler compliqu mettre en oeuvre mais la comprhension de son mode de fonctionnement peut grandement faciliter son utilisation. Il utilise le modle MVC en proposant une sparation des donnes (data models) et du rendu de ces donnes (cell renderers). Dans l'arbre, les lments qui ne possdent pas d'lment fils sont des feuilles (leaf). Chaque lment est associ un objet (user object) qui va permettre de dterminer le libell affich dans l'arbre en utilisant la mthode toString().

16.8.1. La cration d'une instance de la classe JTree La classe JTree possde 7 constructeurs. Tous ceux qui attendent au moins un paramtre acceptent une collection pour initialiser tout ou partie du modle de donnes de l'arbre :

public public JTree(Hashtable public JTree(Vector public JTree(Object[] public JTree(TreeModel public JTree(TreeNode public JTree(TreeNode rootNode, boolean askAllowsChildren);

JTree(); value); value); value); model); rootNode);

Lorsqu'une instance de JTree est cre avec le constructeur par dfaut, l'arbre obtenu contient des donnes par dfaut.

ame; ee; extends JFrame {

JPanel jContentPane = null; jTree = null;

ee() { { e();

ain(String[] args) { e = new TestJtree(); le(true);

ize() { 200); e(getJContentPane()); ame");

JPanel getJContentPane() { = null) { ew javax.swing.JPanel(); Layout(new java.awt.BorderLayout()); (getJTree(), java.awt.BorderLayout.CENTER);

e;

Les trois constructeurs qui attendent en paramtre une collection permettent de crer un arbre avec une racine non affiche qui va contenir comme noeuds fils directs tous les lments contenus dans la collection.

= {"noeud 1","noeud 2","noeud3","noeud 4"}; e(racine);

Dans ce cas, la racine n'est pas affiche. Pour l'afficher, il faut utiliser la mthode setRootVisible()

rue);

Dans ce cas elle se nomme root et possde un commutateur qui permet de refermer ou d'tendre la racine. Pour supprimer ce commutateur, il faut utiliser la mthode jTree.setShowsRootHandles(false)

L'utilisation de l'une ou l'autre des collections n'est pas quivalente. Par exemple, l'utilisation d'une hashtable ne garantit pas l'ordre des noeuds puisque par dfinition cette collection ne gre pas un ordre prcis. Gnralement, la construction d'un arbre utilise un des constructeurs qui attend en paramtre un objet de type TreeModel ou TreeNode car ces deux objets permettent d'avoir un contrle sur l'ensemble des donnes de l'arbre. Leur utilisation sera dtaille dans la section consacre la gestion des donnes de l'arbre. En fonction du nombre d'lments et de l'tat tendu ou non d'un ou plusieurs lments, la taille de l'arbre peut varier : il est donc ncessaire d'inclure le composant JTree dans un composant JScrollPane

jScrollPane

= null;

getJScrollPane() { null) { w JScrollPane(); iewportView(getJTree());

JPanel getJContentPane() { = null) { ew javax.swing.JPanel(); Layout(new java.awt.BorderLayout()); (getJScrollPane(), java.awt.BorderLayout.CENTER);

e;

L'utilisateur peut slectionner un noeud en cliquant sur son texte ou son icne. Un double clic sur le texte ou l'icne d'un noeud permet de l'tendre ou le refermer selon son tat.

16.8.2. La gestion des donnes de l'arbre Chaque arbre commence par un noeud racine. Par dfaut, la racine et ses noeuds fils directs sont visibles. Chaque noeud de l'arbre peut avoir zro ou plusieurs noeuds fils. Un noeud sans noeud fils est appel une feuille de l'arbre (leaf) En application du modle MVC, le composant JTree ne gre pas directement chaque noeud et la faon dont ceux-ci sont organiss et stocks mais il utilise un objet ddi de type TreeModel. Ainsi, comme dans d'autres composants Swing, le composant JTree manipule des objets implmentant des interfaces. Une classe qui encapsule les donnes de l'arbre doit implmenter l'interface TreeModel. Chaque noeud de l'arbre doit implmenter l'interface TreeNode. Pour prciser les donnes contenues dans l'arbre, il faut crer un objet qui va encapsuler ces donnes et les passer au constructeur de la classe Jtree. Cet objet peut tre de type TreeNode ou TreeModel. Un TreeModel stocke les donnes de chaque noeud dans un objet de type TreeNode. Gnralement, le plus simple est de dfinir un type TreeNode personnalis. Swing propose pour cela l'objet DefaultMutableTreeNode. il suffit d'en crer une instance pour stocker les donnes et l'utiliser lors de l'appel du constructeur de la classe JTree. La classe DefaultMutableTreeNode implmente l'interface MutableTreeNode qui ellemme hrite de l'interface TreeNode

e.DefaultMutableTreeNode;

ee() {

{ eeNode racine = new DefaultMutableTreeNode("Racine de l'arbre"); eeNode noeud1 = new DefaultMutableTreeNode("Noeud 1"); 1); eeNode noeud2 = new DefaultMutableTreeNode("Noeud 2");

2); e(racine);

Dans ce cas, une instance de la classe DefaultTreeModel est cre avec la racine fournie en paramtre du constructeur de la classe JTree. Une autre solution permet de crer une instance de la classe DefaultTreeModel et de la passer en paramtre du constructeur de la classe JTree. La mthode setModel() de la classe JTree permet d'associer un modle de donnes l'arbre.

16.8.2.1. L'interface TreeNode Chaque noeud de l'arbre stock dans le modle de donnes implmente l'interface TreeNode. Cette interface dfinit 7 mthodes dont la plupart concernent les relations entre les noeuds :

Mthode

Rle

Enumeration children()

renvoie une collection des noeuds fils

boolean getAllowsChildren()

Renvoie un boolen qui precise si le noeud peut avoir des noeuds fils

TreeNode index)

getChildAt(int Renvoie le paramtre

noeud

fils

correspondant

l'index

fourni

en

int getChildCount()

renvoie le nombre de noeuds fils directs du noeud

int getIndex(TreeNode child)

renvoie l'index du noeud pass en paramtre

TreeNode getParent()

renvoie le noeud pre

boolean isLeaf()

renvoie un boolen qui prcise si le noeud est une feuille

Chaque noeud ne peut avoir qu'un seul pre (hormis le noeud racine qui ne possde pas de pre) et autant de noeuds fils que souhait. La mthode getParent() permet de renvoyer le noeud pre. Elle renvoie null lorsque cette mthode est appele sur le noeud racine. La mthode getChildCount() renvoie le nombre de noeuds fils directs du noeud. La mthode getAllowsChildren() permet de prciser si le noeud peut avoir des noeuds enfants : si elle renvoie false alors le noeud sera toujours une feuille et ne pourra donc jamais avoir de noeuds fils. La mthode isLeaf() renvoie un boolen prcisant si le noeud est une feuille ou non. Une feuille est un noeud qui ne possde pas de noeud fils. Les noeuds fils sont ordonns car l'ordre de reprsentation des donnes peut tre important dans la reprsentation de donnes hirarchiques. La mthode getChildAt() renvoie le noeud fils dont l'index est fourni en paramtre de la mthode. La mthode getIndex() renvoie l'index du noeud fils pass en paramtre.

16.8.2.2. L'interface MutableTreeNode Les 7 mthodes dfinies par l'interface TreeNode ne permettent que de lire des valeurs. Pour mettre jour un noeud, il est ncssaire d'utiliser l'interface MutableTreeNode qui hrite de la mthode TreeNode. Elle dfinit en plus plusieurs mthodes permettant de mettre jour le noeud. void insert(MutableTreeNode child, void remove(int void remove(MutableTreeNode void void setParent(MutableTreeNode void setUserObject(Object userObject); index); index); node); removeFromParent(); parent); int

La mthode insert() permet d'ajouter le noeud fourni en paramtre comme noeud fils la position prcise par le second paramtre. Il existe deux surcharges de la mthode remove() qui permettent de dconnecter un noeud fils de son pre. La premire surcharge attend en paramtre l'index du noeud fils. La seconde surcharge attend en paramtre le noeud dconnecter. Dans tous les cas, il est ncessaire d'utiliser cette mthode sur le noeud pre. La mthode removeFromParent() appele partir d'un noeud permet de supprimer le lien entre le noeud et son pre. La mthode setParent() permet de prciser le pre du noeud.

La mthode setUserObject() permet d'associer un objet au noeud. L'appel la mthode toString() de cet objet permettra de dterminer le libell du noeud qui sera affich.

16.8.2.3. La classe DefaultMutableTreeNode Gnralement, les noeuds crs dans le modle sont des instances de la classe DefaultMutableTreeNode. Cette classe implmente l'interface MutableTreeNode ce qui permet d'obtenir une instance d'un noeud modifiable. Le plus souvent, les noeuds fournis en paramtres des mthodes proposes par Swing sont de type TreeNode. Si l'instance du noeud est de type DefaultTreeNode, il est possible de faire un cast pour accder toutes ses mthodes. La classe propose trois constructeurs dont deux attendent en paramtre l'objet qui sera associ au noeud. L'un des deux attend en plus un boolen qui permet de prciser si le noeud peut avoir des noeuds fils.

Constructeur

Rle

public DefaultMutableTreeNode()

Crer un noeud sans objet associ. Cette association pourra tre faite avec la mthode setObject()

public userObject)

DefaultMutableTreeNode(Object

Crer un noeud en prcisant l'objet qui lui sera associ et qui pourra avoir des noeuds fils

public DefaultMutableTreeNode(Object Crer un noeud dont le boolen prcise s'il userObject, boolean allowsChildren) pourra avoir des fils

Pour ajouter une instance de la classe DefaultMutableTreeNode dans le modle de l'arbre, il est possible d'utiliser la mthode insert() de l'interface MutuableTreeNode ou utiliser la mthode add() de la classe DefaultMutableTreeNode. Celle-ci attend en paramtre une instance du noeud fils ajouter. Elle ajoute le noeud aprs le dernier noeud fils, ce qui vite d'avoir garder une rfrence sur la position o insrer le noeud.

racineNode = new DefaultMutableTreeNode(); division1 = new DefaultMutableTreeNode("Division 1"); division2 = new DefaultMutableTreeNode("Division 2"); n1); n2); aultTreeModel(racineNode));

Il est aussi possible de dfinir sa propre classe qui implmente l'interface MutableTreeNode : une possibilit est de dfinir une classe fille de la classe DefaultMutableTreeNode.

16.8.3. La modification du contenu de l'arbre Les modifications du contenu de l'arbre peuvent se faire au niveau du modle (DefaultTreeModel) ou au niveau du noeud. La mthode getModel() de la classe JTree permet d'obtenir une rfrence sur l'instance de la classe TreeModel qui encapsule le modle de donnes. Il est ainsi possible d'accder tous les noeuds du modle pour les modifier.

Tree.getModel().getRoot(); de)noeudRacine).setUserObject("Racine de l'arbre");

L'interface TreeModel ne propose rien pour permettre la mise jour du modle. Pour cela, il faut utiliser une instance de la classe DefaultTreeModel. Elle propose plusieurs mthodes pour ajouter ou supprimer un noeud : void insertNodeInto(MutableTreeNode child, MutableTreeNode parent, int index) void removeNodeFromParent(MutableTreeNode parent) L'avantage de ces deux mthodes est qu'elles mettent jour le modle mais aussi qu'elles mettent jour la vue en appelant respectivement les mthodes nodesWereInserted() et nodesWereRemoved() de la classe DefaultTreeModel. Ces deux mthodes sont donc pratiques pour faire des mises jour mineures mais elles sont peut adaptes pour de nombreuses mises jour puisqu'elles dclenchent un vnement chacune de leurs utilisations.

16.8.3.1. Les modifications des noeuds fils La classe DefaultMutableTreeNode propose plusieurs mthodes pour mettre jour le modle partir du noeud qu'elle encapsule. void void void void add(MutableTreeNode insert(MutableTreeNode child, remove(int remove(MutableTreeNode child) index) index) child)

int

void void removeFromParent()

removeAllChildren()

Toutes ces mthodes sauf la dernire agissent sur un ou plusieurs noeuds fils. Ces mthodes agissent simplement sur la structure du modle. Elles ne provoquent pas un affichage par la partie vue de ces changements. Pour cela il est ncessaire d'utiliser une des mthodes suivantes proposes par la classe DefaultTreeModel : Mthode void reload() void reload(TreeNode node) void nodesWereInserted(TreeNode node, childIndices) int[] Rle rafraichir toute l'arborescence partir du modle rafraichir toute l'arborescence partir du noeud prcis en paramtre pour le noeud prcis, cette mthode rafraichit les noeuds fils ajouts dont les index sont fournis en paramtre

pour le noeud prcis, cette mthode void nodesWereRemoved(TreeNode node,int[] rafraichit les noeuds fils supprims dont les childIndices, Object[] removedChildren) index sont fournis en paramtre void nodeStructureChanged(TreeNode node) cette mthode est identique la mthode reload()

16.8.3.2. Les vnements mis par le modle Il est possible d'enregistrer un listener de type TreeModelListener sur un objet de type DefaultTreeModel. L'interface TreeModelListener vnements particuliers : Mthode void treeNodesChanged(TreeModelEvent) void treeStructureChanged(TreeModelEvent) void treeNodesInserted(TreeModelEvent) void treeNodesRemoved(TreeModelEvent) dfinit quatre mthodes pour rpondre des

Rle la mthode nodeChanged() ou nodesChanged() est utilise la mthode reload() ou nodeStructureChanged() est utilise la mthode nodeWhereInserted() est utilise la mthode utilise nodeWhereRemoved() est

Toutes ces mthodes ont un objet de type TreeModelEvent qui encapsule l'vnement. La classe TreeModelEvent propose cinq mthodes pour obtenir des informations sur les noeuds impacts par l'vnement. Mthode Object getSource() TreePath getTreePath() Rle renvoie une instance sur le modle de l'arbre (gnralement un objet de type DefaultTreeModel) renvoie le chemin du noeud affect par l'vnement

Object[] getPath() Object[] getChildren() int[] getChildIndices()

Renvoie la succession de noeuds de la racine au noeud parent des noeuds impacts

retourne les index des noeuds modifis

Dans la mthode treeStructureChanged(), seules les mthodes getPath() et getTreePath() fournissent des informations utiles en retournant le noeud qui a t modifi. Dans la mthode treeNodesChanged(), treeNodesRemoved() et treeNodesInserted() les mthodes getPath() et getTreePath() renvoient le noeud pre des noeuds affects. Les mthodes getChildIndices() et getChidren() renvoient respectivement un tableau des index des noeuds fils modifis et un tableau de ces noeuds fils. Dans ces mthodes, les mthodes getPath() et getTreePath() renvoient le noeud pre des noeuds affects. Comme l'objet JTree enregistre ses propres listeners, il n'est pas ncessaire la plupart du temps, d'enregistrer ces listeners hormis pour des besoins spcifiques.

16.8.3.3. L'dition d'un noeud Par dfaut, le composant JTree est readonly. Il est possible d'autoriser l'utilisateur modifier le libell des noeuds en utilisant la mthode setEditable() avec le paramtre true : jTtree.setEditable(true);

Pour diter un noeud, il faut

sur un noeud non slectionn : cliquer rapidement trois fois sur le noeud modifier sur un noeud dj slectionn : cliquer une fois sur le noeud ou appuyer sur la
touche F2 Pour valider les modifications, il suffit d'appuyer sur la touche Entree . Pour annuler les modifications, il suffit d'appuyer sur la touche Esc Il est possible d'enregistrer un listener de type TreeModelListerner pour assurer des traitements lors d'vnements lis l'dition d'un noeud. L'interface TreeModelListener dfinit la mthode treeNodesChanged() qui permet de traiter les vnements de type TreeModelEvent lis la modification d'un noeud.

e(true); .addTreeModelListener(new TreeModelListener() {

eeNodesChanged(TreeModelEvent evt) { rintln("TreeNodesChanged"); uds = evt.getChildren(); s = evt.getChildIndices(); 0; i < noeuds.length; i++) { .println("Index " + indices[i] + ", nouvelle valeur : " ds[i]);

eeStructureChanged(TreeModelEvent evt) { rintln("TreeStructureChanged");

eeNodesInserted(TreeModelEvent evt) { rintln("TreeNodesInserted");

eeNodesRemoved(TreeModelEvent evt) { rintln("TreeNodesRemoved");

16.8.3.4. Les diteurs personnaliss Il est possible de dfinir un diteur particulier pour diter la valeur d'un noeud. Un diteur particulier doit implmenter l'interface TreeCellEditor. Cette interface hrite de l'interface CellEditor qui dfinit plusieurs mthodes utiles pour la cration d'un diteur ddi : Object boolean boolean boolean void void addCellEditorListener( void removeCellEditorListener( CellEditorListener); getCellEditorValue(); isCellEditable(EventObject); shouldSelectCell(EventObject); stopCellEditing(); cancelCellEditing(); CellEditorListener);

L'interface TreeCellEditor ne dfinit qu'une seule mthode : Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row); Cette mthode renvoie un composant qui va permettre l'dition de la valeur du noeud. La valeur initiale est fournie dans le second paramtre de type Object. Les trois arguments de type boolen suivants permettent respectivement de savoir si le noeud est slectionn, est tendu et est une feuille. Swing propose une implmentation de cette interface dans la classe DefaultCellEditor qui permet de modifier la valeur du noeud sous la forme d'une zone de texte, d'une case cocher ou d'une liste droulante grce trois constructeurs :

public DefaultCellEditor(JTextField text); public DefaultCellEditor(JCheckBox box); public DefaultCellEditor(JComboBox combo); La mthode setCellEditor() de la classe JTree permet d'associer le nouvel diteur l'arbre.

e(true); s = { "Element 1", "Element 2", "Element 3", "Element = new JComboBox(elements); ditor editor = new DefaultTreeCellEditor(jTree, TreeCellRenderer(), new DefaultCellEditor(jCombo)); tor(editor);

4"};

16.8.3.5. La dfinition des noeuds ditables Par dfaut, si la mthode setEditable(true) est utilise alors tous les noeuds sont modifiables. Il est possible de dfinir les noeuds de l'arbre qui sont ditables en crant une classe fille de la classe JTree et en redfinissant la mthode isPathEditable(). Cette mthode est appele avant chaque dition d'un noeud. Elle attend en paramtre un objet de type TreePath qui encapsule le chemin du noeud diter. Par dfaut, elle renvoie le rsultat de l'appel la mthode isEditable(). Il est d'ailleurs important, lors de la redfinition de la mthode isPathEditable(), de tenir compte du rsultat de la mthode isEditable() pour s'assurer que l'arbre est modifiable avant de vrifier si le noeud peut tre modifi.

16.8.4. La mise en oeuvre d'actions sur l'arbre

16.8.4.1. Etendre ou refermer un noeud Pour tendre un noeud et ainsi voir ses fils, l'utilisateur peut double cliquer sur l'icne ou sur le libell du noeud. Il peut aussi cliquer sur le petit commutateur gauche de l'icne.

Enfin, il est possible d'utiliser le clavier pour naviguer dans l'arbre l'aide des touches flches haut et bas et des touches flches droite et gauche pour respectivement tendre ou refermer un noeud. Lors d'un appui sur la flche gauche, si le noeud est dj ferm alors c'est le noeud pre qui est slectionn. De la mme faon, lors d'un appui sur la flche droite, si le noeud est tendu alors le premier noeud fils est slectionn. La touche HOME permet de slectionner le noeud racine. La touche END permet de slectionner le noeud qui est la dernire feuille du dernier noeud. Les touches PAGEUP et PAGEDOWN permettent de parcourir rapidement les noeuds de l'arbre. Depuis Java 2 version 1.3, la mthode setToggleClickCount() permet de prciser le nombre de clics ncessaires pour tendre ou refermer un noeud. La classe JTree propose plusieurs mthodes lies aux actions permettant d'tendre ou de refermer un noeud. Mthode public void expandRow (int row) public row) void collapseRow(int Rle Etendre le paramtre noeud dont l'index est fourni en

Refermer le noeud dont l'index est fourni en paramtre Etendre le noeud encapsul dans la classe TreePath fournie en paramtre Refermer le noeud encapsul TreePath fournie en paramtre dans la classe

public void expandPath(TreePath path) public void collapsePath(TreePath path) public boolean isExpanded(int row) public boolean isCollapsed (int row) public boolean isExpanded(TreePath path) public boolean (TreePath path) isCollapsed

Renvoie un boolen qui prcise si le noeud dont l'index est fourni en paramtre est tendu Renvoie un boolen qui prcise si le noeud dont l'index est fourni en paramtre est referm Renvoie un boolen qui prcise si le noeud encapsul dans la classe TreePath fournie en paramtre est tendu Renvoie un boolen qui prcise si le noeud encapsul dans la classe TreePath fournie en paramtre est referm

Par dfaut, le noeud racine est tendu. Les mthodes expandRow() et expandPath() ne permettent que d'tendre les noeuds fils directs du noeud sur lesquel elles sont appliques. Pour tendre les noeuds sousjacents il est ncessaire d'crire du code pour raliser l'opration sur chaque noeud concern de faon rcursive. Pour refermer tous les noeudsx et ne laisser que le noeud racine, il faut utiliser la mthode collapseRow() en lui passant 0 comme paramtre puisque le noeud racine est toujours le premier noeud.

La classe JTree propose deux mthodes pour forcer un noeud tre visible : scrollPathToVisible() et scrollRowToVisible(). Celles-ci ne peuvent fonctionner que si le

composant JTree est inclus dans un conteneur JScrollPane pour permettre au composant de scroller.

ansionListener(new TreeExpansionListener() { eeExpanded(TreeExpansionEvent evt) { rintln("treeExpanded : path=" + evt.getPath()); PathToVisible(evt.getPath());

16.8.4.2. La dtermination du noeud slectionn Pour dterminer le noeud slectionn, il suffit d'utiliser la mthode getLastSelectedPathComponent() de la classe JTree et de caster la valeur retourne dans le type du noeud, gnralement de type DefaultMutableTreeNode. La mthode getObject() du noeud permet d'obtenir l'objet associ au noeud. Si l'objet associ est simplement une chane de caractres ou si la valeur ncessaire est simplement le libell du noeud, il suffit d'utiliser la mthode toString().

outon qui prcise lors d'un clic le noeud slectionn

Button() { l) { utton(); nListener(new java.awt.event.ActionListener() { tionPerformed(java.awt.event.ActionEvent e) { rintln("actionPerformed()"); rintln("Noeud slectionn : " getLastSelectedPathComponent().toString());

16.8.4.3. Le parcours des noeuds de l'arbre Il peut tre ncessaire de parcourir tout ou partie des noeuds de l'arbre pour par exemple faire une recherche dans l'arborescence. Si l'arbre est compos de noeuds de type DefaultMutableTreenode alors l'interface TreeNode propose plusieurs mthodes pour obtenir une numration des noeuds. L'ensemble, ou seulement une partie des donnes, peut tre parcouru dans les deux sens et selon deux types de prsentation des valeurs. Enumeration Enumeration Enumeration Enumeration depthFirstEnumeration(); preorderEnumeration(); postorderEnumeration(); breadthFirstEnumeration();

Dans l'exemple ci-dessous, l'arborescence suivante est utilise :

outon qui prcise lors d'un clic le noeud slectionn

DefaultMutableTreeNode)jTree.getModel().getRoot()).preorderEnumeration(); ements()) { tln(e.nextElement() + " ");

Rsultat : preorder Racine de colors blue violet red yellow sports basketball soccer football hockey food hot pizza ravioli bananas postorder breadthFirst depthFirst l'arbre blue violet red yellow colors basketball soccer football hockey sports hot dogs pizza dogs ravioli bananas food Racine de l'arbre

l'arbre blue Racine de violet colors red sports yellow food colors blue basketball violet soccer red football yellow hockey basketball sports soccer hot dogs football pizza hockey dogs ravioli hot bananas pizza food ravioli Racine de l'arbre bananas

La mthode pathFromAncestorEnumeration(TreeNode ancestor) renvoie une numration des noeuds entre le noeud sur lequel la mthode est appele et le noeud fourni en paramtre. Ainsi le noeud fourni en paramtre doit obligatoirement tre un noeud fils direct ou indirect du noeud sur lequel la mthode est appele. Dans le cas contraire, une exception de type IllegalArgumentException est leve.

16.8.5. La gestion des vnements Il est possible d'attacher des listeners pour rpondre aux vnements lis la slection d'un lment ou l'extension ou la refermeture d'un noeud. 16.8.5.1. La classe TreePath Durant son utilisation, le composant JTree ne gre pas directement les noeuds du modle de donnes. La manipulation de ces noeuds se fait via un index ou une instance de la classe TreePath. L'utilisation de l'index est assez dlicate car seul le noeud racine de l'arbre possde toujours le mme index 0. Pour les autres noeuds, la valeur de l'index dpend de l'tat tendu/referm de chaque noeud puisque seuls les noeuds affichs possdent un index. Il est donc prfrable d'utiliser la classe TreePath. Le modle de donnes utilise des noeuds mais l'interface de l'arbre utilise une autre reprsentation sous la forme de la classe TreePath. La classe DefaultMutableTreeNode est la reprsentation physique d'un noeud, la classe TreePath est la reprsentation logique. Elle encapsule le chemin du noeud dans l'arborescence. Cette classe contient plusieurs mthodes : public Object getLastPathComponent(); public Object getPathComponent(int index); public int getPathCount(); public Object[] getPath(); public TreePath getParentPath(); public TreePath pathByAddingChild(Object child); public boolean isDescendant(TreePath treePath) La mthode getPath() renvoie un tableau d'objets contenant chaque noeud qui compose le chemin encapsul par la classe TreePath. La mthode getLastPathComponent() renvoie le dernier noeud du chemin. La mthode getPathCount() renvoie le nombre de noeuds qui composent le chemin. La mthode getPathComponent() permet de renvoyer le noeud dont l'index dans le chemin est fourni en paramtre. L'lment avec l'index 0 est toujours le noeud racine de l'arbre. La mthode getParentPath() renvoie une instance de la classe TreePath qui encapsule le chemin vers le noeud pre du chemin encapsul. La mthode pathByAddingChild() renvoie une instance de la classe TreePath qui encapsule le chemin issu de l'ajout d'un noeud fils fourni en paramtre. La mthode idDescendant() renvoie un boolen qui prcise si le chemin pass en paramtre est un descendant du chemin encapsul. La classe TreePath ne permet pas de grer le contenu de chaque noeud mais uniquement son chemin dans l'arborescence. Pour accder au noeud partir de son chemin, il faut utiliser la mthode getLastPathComponent(). Pour obtenir un noeud inclus dans le chemin, il faut utiliser la getPathComponent() ou getPath(). Toutes ces mthodes renvoient un objet ou un tableau de type Object. Il est donc ncessaire de raliser un cast vers le type de noeud utilis, gnralement de type DefaultMutableTreeNode.

A partir d'un noeud de type DefaultMutableTreeNode, il est possible d'obtenir l'objet TreePath encapsulant le chemin du noeud. La mthode getPath() permet d'obtenir un tableau d'objets de type TreeNode qu'il suffit de passer au constructeur de la classe TreePath.

eud.getPath(); eePath(chemin);

16.8.5.2. La gestion de la slection d'un noeud La gestion de la slection de noeud dans un composant JTree est dlgue un modle de slection sous la forme d'une classe qui implmente l'interface TreeSelectionModel. Par dfaut, le composant JTree utilise une instance de la classe DefaultTreeSelectionModel. Le modle de slection peut tre configur selon trois modes :

SINGLE_TREE_SELECTION: un seul noeud peut tre slectionn. CONTIGUOUS_TREE_SELECTION: plusieurs noeuds peuvent tre slectionns DISCONTIGUOUS_TREE_SELECTION: plusieurs noeuds peuvent tre slectionns
de faon continue et/ou discontinue (c'est le mode par dfaut). Pour empcher la slection d'un noeud dans l'arbre, il faut supprimer son modle de slection en passant null la mthode setSelectionModel(). condition d'tre contigus.

e()jTree.setSelectionModel(null); La slection d'un noeud peut tre ralise par l'utilisateur ou par l'application : le modle de slection s'assure que celle-ci est ralise en respectant le mode de slection du modle. L'utilisateur peut utiliser la souris pour slectionner un noeud ou appuyer sur la touche Espace sur le noeud courant pour le slectionner. Il est possible de slectionner plusieurs noeuds en fonction du mode en maintenant la touche CTRL enfonce. Avec la touche SHIFT, il est possible selon le mode de slectionner tous les noeuds entre un premier noeud slectionn et le noeud courant. La slection d'un noeud gnre un vnement de type TreeSelectionEvent. Le dernier noeud slectionn peut tre obtenu getLeadSelectionPath() ou getLeadSelectionRow(). en utilisant les mthodes

Par dfaut la slection d'un noeud entraine l'extension des noeuds ascendants correspondant afin de les rendre visibles. Pour empcher ce comportement, il faut utiliser la mthode setExpandSelectedPath() en lui fournissant la valeur false en paramtre. public void setExpandsSelectedPaths(boolean cond); Les classes DefaultTreeSelectionModel et JTree possdent plusieurs mthodes pour grer la slection de noeuds. Certaines de ces mthodes sont communes ces deux classes.

Mthode int getSelectionMode() void setSelectionMode(int mode)

Rle renvoie le mode de slection mettre jour le mode de slection renvoie le premier noeud de la slection courante ou null si aucun noeud n'est slectionn JTree uniquement JTree uniquement JTree uniquement renvoie le dernier path ajout la slection ou identifi comme tel fait de newPath le dernier Path ajout Renvoie le plus grand index de la slection Renvoie le slection plus petit index de la

Object getLastSelectedPathComponent()

TreePath getAnchorSelectionPath() void setAnchorSelectionPath(TreePathpath) TreePath getLeadSelectionPath() setLeadSelectionPath() int getMaxSelectionRow() int getMinSelectionRow() int getSelectionCount() TreePath getSelectionPath() TreePath[] getSelectionPaths() int[] getSelectionRows()

Renvoie le nombre de noeuds inclus dans la slection Renvoie le chemin du premier lment slectionn Renvoie un tableau des chemins des noeuds inclus dans la slection Renvoie un tableau des index noeuds inclus dans la slection des

Boolean isPathSelected (TreePath path)

Renvoie un boolen si le noeud dont le chemin est fourni en paramtre est inclus dans la slection Renvoie un boolen si le noeud dont l'index est fourni en paramtre est inclus dans la slection Renvoie un boolen qui prcise si la slection est vide Vide la slection Enlve de la slection les noeuds dans l'intervalle des index fournis en paramtre Enlve de la slection le noeud dont le chemin est fourni en paramtre Enlve de la slection le noeud dont l'index est fourni en paramtre JTree uniquement Enlve de la slection les noeuds dont les index sont fournis en paramtre JTree uniquement Ajouter la slection les noeuds dont l'intervalle des index est fourni en paramtre Ajouter la slection le noeud dont le

Boolean isRowSelected(int row)

boolean isSelectionEmpty() void clearSelection() void removeSelectionInterval (int row0, int row1) void removeSelectionPath(TreePath path)

void removeSelectionRow (int row)

void removeSelectionRows(int[] rows)

void addSelectionInterval(int row0, int row1) void addSelectionPath(TreePath path)

chemin est fourni en paramtre addSelectionPaths(TreePath[] path) void addSelectionRow(int row) void addSelectionRows(int[] row) void setSelectionInterval(int row1) row0, int Ajouter la slection les noeuds dont les chemins sont fournis en paramtre Ajouter la slection le noeud dont l'index est fourni en paramtre Ajouter la slection les noeuds dont les index sont fournis en paramtre Dfinir la slection avec les noeuds dont les index sont fournis en paramtre JTree uniquement Dfinir la slection avec le noeud dont le chemin est fourni en paramtre Dfinir la slection avec les noeuds dont les chemins sont fournis en paramtre Dfinir la slection avec le noeud dont l'index est fourni en paramtre Dfinir la slection avec les noeuds dont les index sont fournis en paramtre JTree uniquement

setSelectionPath(TreePath path) void setSelectionPaths (TreePath[] path) void setSelectionRow(int row)

void setSelectionRows(int[] row)

16.8.5.3. Les vnements lies la slection de noeuds Lors de la slection d'un noeud, un vnement de type TreeSelectionEvent est mis. Pour traiter cet vnement, le composant doit enregistrer un listener de type TreeSelectionListener. L'interface TreeSelectionListener dfinit une seule mthode : public void valueChanged(TreeSelectionEvent evt)

Listener(new javax.swing.event.TreeSelectionListener() { eChanged(javax.swing.event.TreeSelectionEvent e) {

TreeNode noeud = (DefaultMutableTreeNode) jTree lectedPathComponent(); ull)

ntln("valueChanged() : " + noeud);

La classe TreeSelectionEvent informations sur la slection. Mthode public TreePath[] getPaths() public boolean (TreePath path) isAddedPath

possde

plusieurs

mthodes

pour

obtenir

des

Rle Renvoie un tableau des chemins des noeuds slectionns Renvoie true si le noeud slectionn est ajout la slection.

Renvoie false si le noeud slectionn est retir de la slection TreePath getPath() Renvoie le slectionn chemin du premier noeud

boolean isAddedPath()

Renvoie true si le premier noeud slectionn est ajout la slection. Renvoie false si le premier noeud slectionn est retir de la slection Renvoie l'ancien lead path Renvoie le leader actuel de la slection

TreePath getOldLeadSelection() TreePath getNewLeadSelection()

Un listener de type TreeSelectionListener est enregistr en utilisant la mthode addTreeSelectionListener() de la classe JTree.

Listener(new TreeSelectionListener() {

nged(TreeSelectionEvent e) {

.getLastSelectedPathComponent(); ("getLastSelectedPathComponent=" + obj); ("getPath=" + e.getPath()); ("getNewLeadSelectionPath=" SelectionPath()); ("getOldLeadSelectionPath=" SelectionPath()); e.getPaths();

< paths.length; i++) { ln("Path " + i + "=" + paths[i]);

Un vnement de type TreeSelectionEvent n'est mis que si un changement intervient dans la slection : lors d'un clic sur un noeud, celui-ci est slectionn et un vnement est mis. Lors d'un nouveau clic sur ce mme noeud, le noeud est toujours slectionn mais l'vnement n'est pas mis puisque la slection n'est pas modifie. Dans un listener pour grer les vnements de la souris, il est possible d'utiliser la mthode getPathForLocation() pour dterminer le chemin d'un noeud partir des coordonnes de la souris qu'il faut lui fournir en paramtre. La mthode getPathForLocation() renvoie null si l'utilisateur clique en dehors d'un noeud dans l'arbre.

(new MouseAdapter() { cked(MouseEvent evt) {

ForLocation(evt.getX(), evt.getY()); ) { intln("path= " + path.getLastPathComponent());

Plusieurs autres mthodes peuvent aussi tre utilises dans ce contexte. Mthode TreePath getClosestPathForLocation(int int y) x, Rle Retourne le chemin du noeud le plus proche des coordonnes fournies en paramtre Retourne l'index du noeud le plus proche des coordonnes fournies en paramtre Renvoie un objet de type Rectangle qui reprsente la surface du noeud dont le chemin est fourni en paramtre Retourne le chemin du noeud dont la surface contient les coordonnes fournies en paramtre. Renvoie null si ces coordonnes ne correspondent aucun noeud Renvoie le chemin du noeud dont l'index est fourni en paramtre Renvoie un objet de type Rectangle qui reprsente la surface du noeud dont l'index est fourni en paramtre Renvoie l'index du noeud la position fournie

int getClosestRowForLocation(int x, int y) Rectangle getPathBounds(TreePath path)

TreePath x, int y)

getPathForLocation(int

TreePath getPathForRow(int row)

Rectangle getRowBounds(int row) int getRowForLocation(int x, int y)

16.8.5.4. Les vnements lorsqu'un noeud est tendu ou referm A chaque fois qu'un noeud est tendu ou referm, un vnement de type TreeExpansionEvent est mis. Il est possible de rpondre ces vnements en mettant en place un listener de type TreeExpansionListener. L'interface TreeExpansionListener propose deux mthodes : public void treeExpanded(TreeExpansionEvent treeCollapsed(TreeExpansionEvent event) event) public void

La classe TreeExpansionEvent possde une proprit source qui contient une rfrence sur le composant JTree l'origine de l'vnement et une proprit path qui contient un objet de type TreePath encapsulant le chemin du noeud l'origine de l'vnement. Les valeurs de ces deux proprits peuvent tre obtenues avec leurs getters respectifs : getSource() et getPath().

Listener(new TreeExpansionListener() {

nded(TreeExpansionEvent evt) { ("expand, path=" + evt.getPath());

apsed(TreeExpansionEvent evt) { ("collapse, path=" +

evt.getPath());

Un seul vnement est gnr chaque fois qu'un noeud est tendu ou referm : il n'y a pas d'vnements mis pour les ventuels noeuds fils qui sont tendus ou referms suite l'action.

16.8.5.5. Le contrle des actions pour tendre ou refermer un noeud Il peut tre utile de recevoir un vnement avant qu'un noeud ne soit tendu ou referm. Un listener de type TreeWillExpandListener() peut tre mis en place pour recevoir un vnement de type TreeExpansionEvent lors d'une tentative pour tendre ou refermer un noeud. L'interface TreeWillExpandListener dfinit deux mthodes : public void treeWillCollapse(TreeExpansionEvent evt) throws ExpandVetoException; public void treeWillExpand(TreeExpansionEvent evt) throws ExpandVetoException; Les deux mthodes peuvent lever une exception de type ExpandVetoException. Cette exception est leve si, pendant l'excution d'une de ces mthodes, des conditions sont remplies pour empcher l'action demande par l'utilisateur. Si l'exception n'est pas leve la fin des traitements de la mthode alors l'action est ralise.

cher tous les noeuds tendus de se refermer

dListener(new TreeWillExpandListener() {

Collapse(TreeExpansionEvent event) throws ExpandVetoException { toException(event);

Expand(TreeExpansionEvent event) throws ExpandVetoException {

16.8.6. La personnalisation du rendu Le rendu du composant JTree dpend bien sr dans un premier temps du look and feel utilis mais il est aussi possible de personnaliser plus finement le rendu des noeuds du composant. Il est possible de prciser la faon dont les lignes reliant les noeuds sont rendues via une proprit client nomme lineStyle. Cette proprit peut prendre trois valeurs : Valeur Angled None Horizontal Rle Une ligne angle droit relie chaque noeud fils son noeud pre Aucune ligne n'est affiche entre les noeuds Une simple ligne horizontale spare les noeuds enfants du noeud racine

Pour prciser la valeur de la proprit que le composant doit utiliser, il faut utiliser la mthode putClientProperty() qui attend deux paramtres sous forme de chanes de caractres :

le nom de la proprit sa valeur

ne); y("JTree.lineStyle","Horizontal");

None

Angled

Horizontal

Il est possible de modifier l'apparence de la racine de l'arbre grce deux mthodes de la classe JTree : setRootVisible() et setShowsRootHandles(). La mthode setRootVisible() permet de prciser avec son boolen en paramtre si la racine est affiche ou non.

e(); les(false); rue);

16.8.6.1. Personnaliser le rendu des noeuds Il est possible d'obtenir un contrle total sur le rendu de chaque noeud en dfinissant un objet qui implmente l'interface TreeCellRenderer. Attention, le rendu personnalis est parfois dpendant du look & feel utilis. L'interface TreeCellRenderer ne dfinit qu'une seule mthode : Component getTreeCellRendererComponent(JTree tree, Object value, selected, boolean expanded, boolean leaf, int row, boolean hasFocus) boolean

Cette mthode envoie un composant qui va encapsuler le rendu du noeud. Le premier argument de type JTree encapsule le composant JTree lui-mme. L'argument de type Object encapsule le noeud dont le rendu doit tre gnr. La mthode getCellRenderer() renvoie un objet qui encapsule le TreeCellRenderer. Il est ncessaire de raliser un cast vers le type de cet objet. Swing propose une classe de base DefaultTreeCellRenderer pour le rendu. Elle propose plusieurs mthodes pour permettre de dfinir le rendu. Mthode void setBackgroundNonSelectionColor(Color) void setBackgroundSelectionColor(Color) Rle Permet de dfinir la couleur de fond du noeud lorsqu'il n'est pas slectionn Permet de dfinir la couleur de fond du noeud lorsqu'il est slectionn Permet de dfinir la couleur de la bordure du noeud lorsqu'il est slectionn. Il n'est pas possible de dfinir une bordure pour un noeud slectionn Permet de dfinir la couleur du texte du noeud lorsqu'il n'est pas slectionn Permet de dfinir la couleur du texte du noeud lorsqu'il est slectionn Permet de dfinir la police de caractre utilis pour afficher le texte du noeud Permet de dfinir l'icne associe au noeud lorsque celui-ci est ferm Permet de dfinir l'icne associe au noeud lorsque celui-ci est tendu Permet de dfinir l'icne associe au noeud lorsque celui-ci est une feuille

void setBorderSelectionColor(Color)

void setTextNonSelectionColor(Color) void setTextSelectionColor(Color) void setFont(Font) void setClosedIcon(Icon) void setOpenIcon(Icon) void setLeafIcon(Icon)

Un composant ne peut avoir qu'une seule instance de type TreeCellRenderer. Cette instance sera donc appele pour dfinir le rendu de chaque noeud.

enderer = jTree.getCellRenderer(); nceof DefaultTreeCellRenderer) { rer renderer = (DefaultTreeCellRenderer)cellRenderer; ndNonSelectionColor(Color.gray); ndSelectionColor(Color.black); ctionColor(Color.white); electionColor(Color.black); Color.gray);

Rsultat :

Pour modifier les icnes utilises par les diffrents lments de l'arbre, il faut utiliser les mthodes setOpenIcon(), setClosedIcon() et setLeafIcon(). Mthode setOpenIcon() setClosedIcon() setLeafIcon() Rle prcise l'icne pour un noeud ouvert prcise l'icne pour un noeud ferm prcise l'icne pour une feuille

Pour simplement supprimer l'affichage de l'icne, il suffit de passer null la mthode concerne.

r monRenderer = new DefaultTreeCellRenderer(); n(null); con(null); n(null); Pour prciser une image, il faut crer une instance de la classe ImageIcon encapsulant l'image et la passer en paramtre de la mthode concerne.

rtIcon = new ImageIcon("images/ouvert.gif"); Icon = new ImageIcon("images/ferme.gif"); leIcon = new ImageIcon("images/feuille.gif");

derer treeCellRenderer = new DefaultTreeCellRenderer(); etOpenIcon(ouvertIcon); etClosedIcon(fermeIcon); etLeafIcon(feuilleIcon); Il est aussi possible de dfinir une classe qui hrite de la classe DefaultTreeCellRenderer. Cette classe propose une implmentation par dfaut de l'interface TreeCellRenderer. Comme elle hrite de la classe JLabel, elle possde dj de nombreuses mthodes pour assurer le rendu du noeud sous la forme d'un composant de type tiquette.

ent;

ee; e.DefaultTreeCellRenderer;

llRenderer extends DefaultTreeCellRenderer {

TreeCellRendererComponent(JTree tree, Object value, , boolean expanded, boolean leaf, int row, ) {

endererComponent(tree,value, selected, expanded, ocus);

lectionColor(Color.gray); tionColor(Color.black); lor(Color.white); nColor(Color.black);

Une fois la classe de type DefaultTreeCellRenderer instancie, il faut utiliser la mthode setCellRenderer() de la classe JTree pour indiquer l'arbre d'utiliser cette classe pour le rendu.

rer(new MonTreeCellRenderer()); La cration d'une classe fille de la classe DefaultTreeCellRenderer ne fonctionne correctement qu'avec les look and feel Metal et Windows car le look and feel Motif dfinit son propre Renderer.

16.8.6.2. Les bulles d'aides (Tooltips) Le composant JTree ne propose pas de support pour les bulles d'aide en standard. Pour permettre un composant JTree d'afficher une bulle d'aide, il faut :

enregistrer le composant JTree auprs du ToolTipManager dfinir le contenu de la bulle d'aide dans le Renderer
L'enregistrement du composant auprs du ToolTipManager se fait en utilisant la mthode registerComponent() sur l'instance partage.

nstance().registerComponent(jTree); erer()).setToolTipText("Arborescence des donnes"); L'inconvnient de cette mthode est que la bulle d'aide est toujours la mme quelque soit la position de la souris sur tous les noeuds du composant. Pour assigner une bulle d'aide particulire chaque noeud, il est ncessaire d'utiliser la mthode setToolTipText() dans la mthode getTreeCellRendererComponent() d'une instance fille de la classe DefaultTreeCellRenderer

derer(new DefaultTreeCellRenderer() {

nt getTreeCellRendererComponent(JTree tree, Object value, lected, boolean expanded, boolean leaf, int row, sFocus) {

eCellRendererComponent(tree, value, selected, expanded, leaf, row, ); xt(value.toString());

haredInstance().registerComponent(jTree);

16.9. Les menus


Les menus de Swing proposent certaines caractristiques intressantes en plus de celles proposes par un menu standard :

les lments de menu peuvent contenir une icne les lments de menu peuvent tre de type bouton radio ou case cocher les lments de menu peuvent avoir des raccourcis clavier (accelerators)
Les menus sont mis en oeuvre dans Swing avec un ensemble de classe :

JMenuBar : encapsule une barre de menus JMenu : encapsule un menu JMenuItem : encapsule un lment d'un menu JCheckBoxMenuItem : encapsule un lment d'un menu sous la forme d'une case cocher JRadioButtonMenuItem : encapsule un lment d'un menu sous la forme d'un bouton radio JSeparator : encapsule un lment d'un menu sous la forme d'un sparateur JPopupMenu : encapsule un menu contextuel Toutes ces classes hritent de faon directe ou indirecte de la classe JComponent.

Les lments de menus cliquables hritent de la classe JAbstractButton. JMenu hrite de la classe JMenuItem et non pas l'inverse car chaque JMenu contient un JMenuItem implicite qui encapsule le titre du menu. La plupart des classes utilises pour les menus implmentent l'interface MenuElement. Cette interface dfinit des mthodes pour la gestion des actions standards de l'utilisateur. Ces actions sont gres par la classe MenuSelectionManager.

test.swing.menu;

*;

wing1 extends JMenuBar {

1() {

que qui affiche l'action du menu utilis

icherMenuListener = new ActionListener() { onPerformed(ActionEvent event) { ntln("Elment de menu [" + event.getActionCommand() s.");

u Fichier

= new JMenu("Fichier"); ew JMenuItem("Nouveau", 'N'); ener(afficherMenuListener); em); em("Ouvrir", 'O'); ener(afficherMenuListener); em); em("Sauver", 'S'); ener(afficherMenuListener); Separator(1);

em); em("Quitter"); ener(afficherMenuListener); em);

u Editer

new JMenu("Editer"); em("Copier"); ener(afficherMenuListener); r(KeyStroke.getKeyStroke('C', Toolkit.getDefaultToolkit() utKeyMask(), false)); m); em("Couper"); ener(afficherMenuListener); r(KeyStroke.getKeyStroke('X', Toolkit.getDefaultToolkit() utKeyMask(), false)); m); em("Coller"); ener(afficherMenuListener); r(KeyStroke.getKeyStroke('V', Toolkit.getDefaultToolkit() utKeyMask(), false)); m);

u Divers

new JMenu("Divers"); r1 = new JMenu("Sous menu 1");

ener(afficherMenuListener); em("Sous menu 1 1"); (item); ener(afficherMenuListener); rs2 = new JMenu("Sous menu 1 2"); em("Sous menu 1 2 1"); d(item); (sousMenuDivers2);

sMenuDiver1); oxMenuItem("Valid"); m); ener(afficherMenuListener); rator(); Group = new ButtonGroup(); uttonMenuItem("Cas 1"); m); ener(afficherMenuListener); em); uttonMenuItem("Cas 2"); m); ener(afficherMenuListener); em); rator(); m = new JMenuItem("Autre", "about_32.png"))); ener(afficherMenuListener); la barre de menus

ain(String s[]) { JFrame("Test de menu");

oseOperation(JFrame.EXIT_ON_CLOSE); new TestMenuSwing1()); ze(new Dimension(250, 200));

rue);

Rsultat :

16.9.1. La classe JMenuBar La classe JMenuBar encapsule une barre de menus qui contient zro ou plusieurs menus. La classe JMenuBar utilise la classe DefaultSingleSelectionModel comme modle de donnes : un seul de ces menus peut tre activ un instant T. Pour ajouter des menus la barre de menus, il faut utiliser la mthode add() de la classe JMenuBar qui attend en paramtre l'instance du menu. Pour ajouter la barre de menus une fentre, il faut utiliser la mthode setJMenuBar() d'une instance des classes JFrame, JInternalFrame, JDialog ou JApplet. Comme la classe JMenuBar hrite de la classe JComponent, il est aussi possible d'instancier plusieurs JMenuBar et de les insrer dans un gestionnaire de positionnement comme n'importe quel composant. Ceci permet aussi de placer le menu sa guise.

ain(String s[]) { JFrame("Test de menu"); oseOperation(JFrame.EXIT_ON_CLOSE); u = new TestMenuSwing1(); ne().add(menu, BorderLayout.SOUTH); ze(new Dimension(250, 200));

rue);

Rsultat :

Swing n'impose pas d'avoir un unique menu par fentre : il est possible d'avoir plusieurs menus dans une mme fentre.

ain(String s[]) { JFrame("Test de menu"); oseOperation(JFrame.EXIT_ON_CLOSE); new TestMenuSwing1()); u = new TestMenuSwing1(); ne().add(menu, BorderLayout.SOUTH); ze(new Dimension(250, 200));

rue);

La classe JMenuBar ne possde qu'un seul constructeur sans paramtre. Les principales mthodes de la classe JMenuBar sont : Mthodes JMenu add(JMenu) JMenu getMenu(int) int getMenuCount() MenuElement[] getSubElements() boolean isSelected() void setMenuHelp (JMenu) Rle Ajouter un menu la barre de menus Obtenir le menu dont l'index est fourni en paramtre Obtenir le nombre de menus de la barre de menus Obtenir un tableau de tous les menus Retourner true slectionn si un composant du menu et est lve

Cette mthode n'est pas implmente systmatiquement une exception

16.9.2. La classe JMenuItem La classe JMenuItem encapsule les donnes d'un lment de menu (libell et/ou image). Elle hrite de la classe AbstractButton. Le comportement est similaire mais diffrent de celui d'un bouton : avec la classe JMenuItem, le composant est considr comme slectionn ds que le curseur de la souris passe dessus. Les lments de menus peuvent tre associs deux types de raccourcis clavier :

les accelerators : ils sont hrits de JComponent : ce sont des touches (par

exemple les touches de fonctions) ou des combinaisons de touches avec les touches shift, Ctrl ou Alt qui sont affiches la droite du libell de l'lment du menu les mnemonics : ils apparaissent sous la forme d'une lettre souligne. Ils sont utilisables seulement sur certaines plate-formes (par exemple en combinaison avec la touche Alt sous Windows). La mthode setAccelerator() permet d'associer un accelerator un lment de type JMenuItem. Un mnemonic peut tre associ un JMenuItm de deux faons :

soit dans la surcharge du constructeur prvue cet effet soit en utilisant la mthode setMnemonic()

Le mnemonic correspond un caractre qui doit obligatoirement tre contenu dans le libell. Un lment de menu peut contenir uniquement une image ou tre compos d'un libell et d'une image. Une image peut tre associe un JMenuItem de deux faons :

soit dans une des surcharges du constructeur prvues cet effet

item = new JMenuItem("Autre", new ImageIcon("about_32.png")); item = new JMenuItem(new ImageIcon("about_32.png"));

soit en utilisant la mthode setIcon

item.setIcon(new ImageIcon("about_32.png"));

16.9.3. La classe JPopupMenu La classe JPopupMenu encapsule un menu flottant qui n'est pas rattach une barre de menus mais un composant. La cration d'un JPopMenu est similaire la cration d'un JMenu. Il est prfrable d'ajouter un lment de type JMenuItem grce la mthode add() de la classe JPopupMenu mais on peut aussi ajouter n'importe quel lment qui hrite de la classe Component en utilisant une surcharge de la mthode add(). Il est possible d'ajouter un lment un index prcis en utilisant la mthode insert(). La mthode addSeparator() permet d'ajouter un lment sparateur. Pour afficher un menu flottant, il faut ajouter un listener sur l'vnement dclenchant et utiliser la mthode show() de la classe JPopupMenu.

test.swing.menu;

ion; ActionEvent; ActionListener; MouseAdapter; MouseEvent;

ame; nuBar; nuItem; pupMenu; xtField;

wing2 extends JMenuBar {

pup;

2() {

ull;

que qui affiche l'action du menu utilis

icherMenuListener = new ActionListener() {

onPerformed(ActionEvent event) { ntln("Elment de menu [" + event.getActionCommand() s.");

Menu(); em("Copier"); ener(afficherMenuListener);

em("Couper"); ener(afficherMenuListener);

ouseEvent(MouseEvent e) {

ain(String s[]) { = new JFrame("Test de menu divers"); exte = new JTextField(); oseOperation(JFrame.EXIT_ON_CLOSE); g2 tms = new TestMenuSwing2();

ener(new MouseAdapter() {

eClicked(MouseEvent e) { ntln("mouse clicked"); e);

ePressed(MouseEvent e) { ntln("mouse pressed"); e);

eReleased(MouseEvent e) { ntln("mouse released"); e);

icherPopup(MouseEvent e) { rigger()) { ow(texte, e.getX(), e.getY());

ze(new Dimension(250, 200));

rue);

Le plus simple pour tre multiplateforme est de tester sur tous les vnements de la souris ceux qui permettent l'affichage du menu flottant. Ce test est ralis grce la mthode isPopupTrigger() de la classe MouseEvent. La proprit invoker encapsule le composant l'origine de l'affichage du menu droulant. La proprit borderPaint indique si la bordure du menu droulant doit tre dessine. La proprit visible indique si le menu droulant est affich. La proprit location indique les coordonnes d'affichage du menu droulant

Un objet de type JPopupMenu peut mettre des vnements de type PopupMenuEvent. Ceux-ci sont traits par un listener de type PopupMenuListener qui dfinit trois mthodes :

Mthode

Rle

popupMenuCanceled()

mthode appele avant que l'affichage du menu droulant ne soit annul

popoupMenuWillBecomeInvisible()

mthode appele avant que le menu droulant ne devienne invisible

popoupMenuWillBecomeVisible()

mthode appele avant que le menu droulant ne devienne visible. Cette mthode permet de personnaliser l'affichage des lments du menu en fonction du contexte (exemple : rendre actif ou non certains lments du menu)

16.9.4. La classe JMenu La classe JMenu encapsule un menu qui est attach un objet de type JMenuBar ou un autre objet de type JMenu. Dans ce second cas, l'objet est un sous menu. Il est possible d'ajouter un lment sous la forme d'un objet de type JMenuItem, Component ou Action en utilisant la mthode add(). Chaque lment du menu possde un index. La mthode addSeparator() permet d'ajouter un lment de type sparateur. La mthode remove() permet de supprimer un lment du menu en fournissant en paramtre l'instance de l'lment ou son index. Si la suppression russie, les index des lments suivants sont dcrments d'une unit. La classe JMenu possde plusieurs proprits :

Proprit

Rle

popupMenu

JPopupMenu qui encapsule les lments du menu

topLevelMenu

proprit en lecture seule qui prcise si le menu est attach un JMenuBar. La valeur false indique que le menu est un sous-menu attach un autre menu

itemCount

indique le nombre d'lments du menu (incluant les sparateurs)

delay

prcise le temps en millisecondes avant l'affichage du menu

menuComponentCount indique le nombre de composants du menu

tearOff

ne pas utiliser cette proprit qui lve une exception de type Error

La mthode getMenuComponent() permet d'obtenir le composant du menu dont l'index est fourni en paramtre. La mthode getItem() permet d'obtenir le JMenuItem dont l'index est fourni en paramtre. La mthode menuComponents() renvoie un tableau des composants du menu. La mthode isMenuComponent() renvoie un boolen qui prcise si le composant fourni en paramtre est inclus dans les lments du menu. Un vnement de type MenuEvent est mis lorsque le titre du menu est cliqu. Un listener de type MenuListener permet de s'abonner ces vnements. L'interface MenuListener dfinie trois mthodes qui possdent un paramtre de type MenuEvent :

Mthodes

Rle

menuCanceled()

invoque lorsque le menu est effac

menuDeselected()

invoque lorsque le titre du menu est dslectionn

menuSelected()

invoque lorsque le titre du menu est slectionn

16.9.5. La classe JCheckBoxMenuItem Cette classe encapsule un lment du menu qui contient une case cocher. Elle possde de nombreux constructeurs qui permettent de prciser le texte, une icne et l'tat de la case cocher.

La proprit state() permet de connatre ou de dfinir l'tat de la case cocher.

16.9.6. La classe JRadioButtonMenuItem Cette classe encapsule un lment de menu qui contient un bouton radio. A un instant donn, un seul des boutons radio associs un mme groupe peut tre slectionn. La dfinition de ce groupe se fait en utilisant la classe ButtonGroup. C'est d'ailleurs cette classe qui propose la mthode getSelected() pour connatre le bouton radio slectionn dans le groupe.

rator(); Group = new ButtonGroup(); uttonMenuItem("Cas 1"); m); ener(afficherMenuListener); em); uttonMenuItem("Cas 2"); m); ener(afficherMenuListener); em); rator();

16.9.7. La classe JSeparator La mthode addSeparator() des classes JMenu et JPopupMenu instancie un objet de type JSeparator et l'ajoute la liste des lments du menu. La classe JSeparator encapsule un sparateur dans un menu. Remarque : L'utilisation de cette classe ne se limite pas aux menus car elle peut aussi tre utilise comme un composant de l'interface.

test.swing.menu;

ion;

; Layout; tton; ame; nel; parator; xtField;

wing3 extends JPanel {

3() {

ayout(this, BoxLayout.Y_AXIS)); (BoxLayout.X_AXIS); (BoxLayout.X_AXIS); (BoxLayout.X_AXIS); (BoxLayout.X_AXIS); (BoxLayout.X_AXIS); on("Bouton 1")); on("Bouton 2")); on("Bouton 3")); rator()); Field("")); rator()); on("Bouton 4")); on("Bouton 5")); on("bouton 6"));

ain(String s[]) { JFrame("Test separator"); oseOperation(JFrame.EXIT_ON_CLOSE); ne(new TestMenuSwing3()); ze(new Dimension(250, 200));

rue);

Rsultat :

16.10. L'affichage d'une image dans une application.


Pour afficher une image dans une fentre, il y a plusieurs solutions. La plus simple consiste utiliser le composant JLabel qui est capable d'afficher du texte mais aussi une image

test;

Layout; geIcon; ame; bel;

xtends JFrame { long serialVersionUID = 1L; titre) {

seOperation(JFrame.EXIT_ON_CLOSE);

JLabel(new ImageIcon("Duke.gif") ); rderLayout.CENTER);

ain(String[] args) { onApp("Afficher image"); e);

Dans l'exemple ci-dessus, le fichier contenant l'image doit tre la racine des fichiers class : aucun chemin n'est prcis donc c'est le chemin relatif au rpertoire d'excution de l'application qui est retenu. Il est possible de prciser un chemin absolu mais cela limite les possibilits de dploiement de l'application.

C:\MonApp\src>javac com/jmdoudoux/test/MonApp.java C:\MonApp\src>java com.jmdoudoux.test.MonApp Il est possible de dfinir un composant personnalis qui hrite de la classe JPanel qui va se charger d'afficher l'image. Historiquement, c'est la classe java.awt.Toolkit qui peut tre utilise pour charger une image.

test;

ion;

cs;

racker;

t;

he une image

age extends Panel { long serialVersionUID = 1L;

String filename) { tDefaultToolkit().getImage("./duke.gif");

= new MediaTracker(this); e, 0);

e) { e();

ize(new Dimension(image.getWidth(this), image s)));

aphics g) { 0, 0, null);

L'inconvnient d'utiliser la classe Toolkit pour charger une image est que ce chargement se fait de faon asynchrone. Il faut alors utiliser une instance de la classe MediaTracker pour patienter le temps du chargement de l'image et ainsi pouvoir dterminer sa taille pour la reporter sur la taille du composant. A partir de Java 1.4, il est aussi possible d'utiliser la classe javax.imageio.ImageIO pour simplifier le code qui charge l'image.

test;

ion; cs;

BufferedImage;

tion; mageIO;

he une image

age extends Panel {

long serialVersionUID = 1L; e image;

String nomFichier) {

read(new File(nomFichier));

dSize(new Dimension(image.getWidth(), t())); on ie) { ce();

aphics g) { 0, 0, null);

Il suffit alors d'utiliser le composant dans la fentre

test; Layout; ame;

tends JFrame { long serialVersionUID = 1L; titre) {

seOperation(JFrame.EXIT_ON_CLOSE);

heImage = new AfficheImage("Duke.gif"); BorderLayout()); age, BorderLayout.CENTER);

ain(String[] args) { onApp("Afficher image"); e);

Malheureusement, ces deux solutions ne fonctionnent pas si l'application est package sous la forme d'une archive qui contient l'image car l'API java.io n'est pas capable de lire une ressource dans l'archive jar. Il faut utiliser le classloader pour charger l'image sous la forme d'une ressource. L'avantage de cette solution c'est qu'elle fonctionne que l'application soit package ou non.

test;

ion; cs;

racker;

t;

he une image

age extends Panel { long serialVersionUID = 1L;

String filename) { this.getClass().getResource("Duke.gif"); tDefaultToolkit().getImage(url);

= new MediaTracker(this); e, 0);

e) { e();

ize(new Dimension(image.getWidth(this), image s)));

aphics g) { 0, 0, null);

Le fichier contenant l'image doit tre accessible par le classloader dans le classpath, par exemple :

La suite de ce chapitre sera dveloppe dans une version future de ce document

[ Prcdent ] [ Sommaire ] [ Suivant ] [Tlcharger ]

[Accueil ]

54 commentaires

Copyright (C) 1999-2013 Jean-Michel DOUDOUX. Vous pouvez copier, redistribuer et/ou modifier ce document selon les termes de la Licence de Documentation Libre GNU, Version 1.1 ou toute autre version ultrieure publie par la Free Software Foundation; les Sections Invariantes tant constitus du chapitre Prambule, aucun Texte de Premire de Couverture, et aucun Texte de Quatrime de Couverture. Une copie de la licence est incluse dans la section GNU FreeDocumentation Licence. La version la plus rcente de cette licence est disponible l'adresse : GNU Free Documentation Licence.

Responsables bnvoles de la rubrique Java : mlny84 - Mickael Baron Contacter par email

Developpez.com
Nous contacter Participez Informations lgales

Services
Forum Java Blogs Hbergement

Partenaires
Hbergement Web Copyright 2000-2013 - www.developpez.com