C'est maintenant que les choses compliquées vont commencer !
Par contre, il va falloir faire la lumière sur certaines choses...
Vous commencez à connaître les arbres, cependant je vous ai caché certaines choses afin de ne pas surcharger le début de ce chapitre.
Voyons : votre
JTree est en fait composé de plusieurs objets. Vous vous doutez bien que pour un composant aussi complexe que celui-ci, il y a du monde au balcon...
Voici une liste des objets que vous serez susceptibles d'utiliser avec ce composant (il y a cinq interfaces et une classe concrète...) :
- TreeModel : c'est lui qui contient les noeuds de votre arbre ;
- TreeNode : noeuds et structure de votre arbre ;
- TreeSelectionModel : modèle de sélection de tous vos noeuds ;
- TreePath : objet qui vous permet de connaître le chemin d'un noeud dans l'arbre et voici notre classe concrète ;
- TreeCellRenderer : interface vous permettant de modifier l'apparence d'un noeud ;
- TreeCellEditor : éditeur utilisé lorsqu'un noeud est éditable.
Vous allez voir que, même si ces objets sont nombreux, leur utilisation, avec un peu de pratique, n'est pas si compliquée que ça... Nous allons commencer par quelque chose d'assez simple : modifier le libellé d'un noeud !
C'est bon, on a déjà trouvé ! Il suffit d'invoquer la méthode setEditable(Boolean bool)
de notre JTree !
Tout à fait !
Cependant, vous serez peut-être amenés à sauvegarder le nouveau nom de votre noeud... Il vous faudra donc déclencher un traitement lors de la modification d'un noeud.

Pour faire cela, nous allons utiliser l'objet
TreeModel que nous allons écouter afin de déterminer ce qui se passe sur notre arbre !
Voici un exemple de code utilisant un
DefaultTreeModel (classe implémentant l'interface
TreeModel) ainsi qu'une implémentation de l'interface
TreeModelListener afin d'écouter le dit objet :
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 | import java.awt.BorderLayout;
import java.io.File;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
public class Fenetre extends JFrame {
private JTree arbre;
private DefaultMutableTreeNode racine;
//Notre objet modèle
private DefaultTreeModel model;
//On passe maintenant le nom du look and feel à utiliser en paramètre du constructeur
public Fenetre(){
this.setSize(200, 300);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("JTree");
listRoot();
this.setVisible(true);
}
private void listRoot(){
this.racine = new DefaultMutableTreeNode();
int count = 0;
for(File file : File.listRoots())
{
DefaultMutableTreeNode lecteur = new DefaultMutableTreeNode(file.getAbsolutePath());
try {
for(File nom : file.listFiles()){
DefaultMutableTreeNode node = new DefaultMutableTreeNode(nom.getName()+"\\");
lecteur.add(this.listFile(nom, node));
}
} catch (NullPointerException e) {}
this.racine.add(lecteur);
}
//On crée notre modèle
this.model = new DefaultTreeModel(this.racine);
//Et nous allons écouter ce que notre modèle a à nous dire !
this.model.addTreeModelListener(new TreeModelListener() {
/**
* Méthode appelée lorsqu'un noeud a changé
*/
public void treeNodesChanged(TreeModelEvent evt) {
System.out.println("Changement dans l'arbre");
Object[] listNoeuds = evt.getChildren();
int[] listIndices = evt.getChildIndices();
for (int i = 0; i < listNoeuds.length; i++) {
System.out.println("Index " + listIndices[i] + ", nouvelle valeur : "
+ listNoeuds[i]);
}
}
/**
* Méthode appelée lorsqu'un noeud est inséré
*/
public void treeNodesInserted(TreeModelEvent event) {
System.out.println("Un noeud a été inséré !");
}
/**
* Méthode appelée lorsqu'un noeud est supprimé
*/
public void treeNodesRemoved(TreeModelEvent event) {
System.out.println("Un noeud a été retiré !");
}
/**
* Méthode appelée lorsque la structure d'un noeud a été modifiée
*/
public void treeStructureChanged(TreeModelEvent event) {
System.out.println("La structure d'un noeud a changé !");
}
});
//On crée, avec notre hiérarchie, un arbre
arbre = new JTree();
//On passe notre modèle à notre arbre
//===> on pouvait aussi passer l'objet TreeModel au constructeur du JTree
arbre.setModel(model);
arbre.setRootVisible(false);
//On rend notre arbre éditable
arbre.setEditable(true);
this.getContentPane().add(new JScrollPane(arbre), BorderLayout.CENTER);
}
private DefaultMutableTreeNode listFile(File file, DefaultMutableTreeNode node){
int count = 0;
if(file.isFile())
return new DefaultMutableTreeNode(file.getName());
else{
for(File nom : file.listFiles()){
count++;
//pas plus de 5 enfants par noeud
if(count < 3){
DefaultMutableTreeNode subNode;
if(nom.isDirectory()){
subNode = new DefaultMutableTreeNode(nom.getName()+"\\");
node.add(this.listFile(nom, subNode));
}else{
subNode = new DefaultMutableTreeNode(nom.getName());
}
node.add(subNode);
}
}
return node;
}
}
public static void main(String[] args){
//nous allons créer des fenêtres avec des looks différents
//Cette instruction permet de récupérer tous les looks du système
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (InstantiationException e) {
} catch (ClassNotFoundException e) {
} catch (UnsupportedLookAndFeelException e) {
} catch (IllegalAccessException e) {}
Fenetre fen = new Fenetre();
}
}
|
Ce qui m'a donné chez moi :
Le dossier '
toto' s'appelait '
CNAM/' : vous pouvez voir que lorsque nous changeons le nom d'un noeud, la méthode
treeNodesChanged(TreeModelEvent evt)
est invoquée !
Vous voyez que, mis à part le fait que plusieurs objets sont utilisés, ce n'est pas si compliqué que ça...
Maintenant, je vous propose de voir comment ajouter des noeuds à notre arbre !
Pour ce faire, nous allons utiliser un bouton qui va nous demander de spécifier le nom du nouveau noeud, ceci via un
JOptionPane.
Voici un code d'exemple :
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155 | import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class Fenetre extends JFrame {
private JTree arbre;
private DefaultMutableTreeNode racine;
private DefaultTreeModel model;
private JButton bouton = new JButton("Ajouter");
//On passe maintenant le nom du look and feel à utiliser en paramètre du constructeur
public Fenetre(){
this.setSize(200, 300);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("JTree");
//On invoque la méthode de construction de notre arbre
listRoot();
bouton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event) {
if(arbre.getLastSelectedPathComponent() != null){
JOptionPane jop = new JOptionPane();
String nodeName = jop.showInputDialog("Saisir un nom de noeud");
if(nodeName != null && !nodeName.trim().equals("")){
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)arbre.getLastSelectedPathComponent();
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(nodeName);
parentNode.add(childNode);
model.insertNodeInto(childNode, parentNode, parentNode.getChildCount()-1);
model.nodeChanged(parentNode);
}
}
else{
System.out.println("AUCUNE SELECTION ! ! !");
}
}
});
this.getContentPane().add(bouton, BorderLayout.SOUTH);
this.setVisible(true);
}
private void listRoot(){
this.racine = new DefaultMutableTreeNode();
int count = 0;
for(File file : File.listRoots())
{
DefaultMutableTreeNode lecteur = new DefaultMutableTreeNode(file.getAbsolutePath());
try {
for(File nom : file.listFiles()){
DefaultMutableTreeNode node = new DefaultMutableTreeNode(nom.getName()+"\\");
lecteur.add(this.listFile(nom, node));
}
} catch (NullPointerException e) {}
this.racine.add(lecteur);
}
//On crée, avec notre hiérarchie, un arbre
arbre = new JTree();
this.model = new DefaultTreeModel(this.racine);
arbre.setModel(model);
arbre.setRootVisible(false);
arbre.setEditable(true);
arbre.getModel().addTreeModelListener(new TreeModelListener() {
public void treeNodesChanged(TreeModelEvent evt) {
System.out.println("Changement dans l'arbre");
Object[] listNoeuds = evt.getChildren();
int[] listIndices = evt.getChildIndices();
for (int i = 0; i < listNoeuds.length; i++) {
System.out.println("Index " + listIndices[i] + ", noeud déclencheur : "
+ listNoeuds[i]);
}
}
public void treeNodesInserted(TreeModelEvent event) {
System.out.println("Un noeud a été inséré !");
}
public void treeNodesRemoved(TreeModelEvent event) {
System.out.println("Un noeud a été retiré !");
}
public void treeStructureChanged(TreeModelEvent event) {
System.out.println("La structure d'un noeud a changé !");
}
});
this.getContentPane().add(new JScrollPane(arbre), BorderLayout.CENTER);
}
private DefaultMutableTreeNode listFile(File file, DefaultMutableTreeNode node){
int count = 0;
if(file.isFile())
return new DefaultMutableTreeNode(file.getName());
else{
for(File nom : file.listFiles()){
count++;
//pas plus de 5 enfants par noeud
if(count < 3){
DefaultMutableTreeNode subNode;
if(nom.isDirectory()){
subNode = new DefaultMutableTreeNode(nom.getName()+"\\");
node.add(this.listFile(nom, subNode));
}else{
subNode = new DefaultMutableTreeNode(nom.getName());
}
node.add(subNode);
}
}
return node;
}
}
public static void main(String[] args){
//nous allons créer des fenêtres avec des looks différents
//Cette instruction permet de récupérer tous les looks du système
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (InstantiationException e) {
} catch (ClassNotFoundException e) {
} catch (UnsupportedLookAndFeelException e) {
} catch (IllegalAccessException e) {}
Fenetre fen = new Fenetre();
}
}
|
Vous remarquerez que nous avons ajouté des variables d'instances afin d'y avoir accès dans toute notre classe !
Voici quelques captures d'écran :
Là non plus, rien d'extraordinairement compliqué, mis à part cette portion de code :
Code : Java | parentNode = (DefaultMutableTreeNode)arbre.getLastSelectedPathComponent();
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(nodeName);
DefaultMutableTreeNode parentNode.add(childNode);
model.insertNodeInto(childNode, parentNode, parentNode.getChildCount()-1);
model.nodeChanged(parentNode);
|
Tout d'abord, nous récupérons le dernier noeud sélectionné avec
parentNode = (DefaultMutableTreeNode)arbre.getLastSelectedPathComponent();
; ensuite, nous créons un nouveau noeud avec
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(nodeName);
et nous l'ajoutons dans notre noeud parent avec l'instruction
parentNode.add(childNode);
, mais nous devons spécifier à notre modèle que celui-ci a un nouveau noeud et donc, qu'il a changé, ceci avec les instructions :
Code : Java | model.insertNodeInto(childNode, parentNode, parentNode.getChildCount()-1);
model.nodeChanged(parentNode);
|
Et voilà !
Avant de vous laisser, il me reste encore à vous montrer... un code !
Celui-ci permet de retirer dynamiquement un noeud d'un arbre !

Inutile de le commenter, celui-ci est très clair :
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168 | import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class Fenetre extends JFrame {
private JTree arbre;
private DefaultMutableTreeNode racine;
private DefaultTreeModel model;
private JButton bouton = new JButton("Ajouter"), effacer = new JButton("Effacer");
//On passe maintenant le nom du look and feel à utiliser en paramètre du constructeur
public Fenetre(){
this.setSize(200, 300);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("JTree");
//On invoque la méthode de construction de notre arbre
listRoot();
bouton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event) {
if(arbre.getLastSelectedPathComponent() != null){
JOptionPane jop = new JOptionPane();
String nodeName = jop.showInputDialog("Saisir un nom de noeud");
if(nodeName != null && !nodeName.trim().equals("")){
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)arbre.getLastSelectedPathComponent();
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(nodeName);
parentNode.add(childNode);
model.insertNodeInto(childNode, parentNode, parentNode.getChildCount()-1);
model.nodeChanged(parentNode);
}
}
else{
System.out.println("AUCUNE SELECTION ! ! !");
}
}
});
effacer.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event) {
if(arbre.getLastSelectedPathComponent() != null){
DefaultMutableTreeNode node = (DefaultMutableTreeNode)arbre.getLastSelectedPathComponent();
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)node.getParent();
model.removeNodeFromParent(node);
model.nodeChanged(parentNode);
}
else{
System.out.println("AUCUNE SELECTION ! ! !");
}
}
});
JPanel pan = new JPanel();
pan.add(bouton);
pan.add(effacer);
this.getContentPane().add(pan, BorderLayout.SOUTH);
this.setVisible(true);
}
private void listRoot(){
this.racine = new DefaultMutableTreeNode();
int count = 0;
for(File file : File.listRoots())
{
DefaultMutableTreeNode lecteur = new DefaultMutableTreeNode(file.getAbsolutePath());
try {
for(File nom : file.listFiles()){
DefaultMutableTreeNode node = new DefaultMutableTreeNode(nom.getName()+"\\");
lecteur.add(this.listFile(nom, node));
}
} catch (NullPointerException e) {}
this.racine.add(lecteur);
}
//On crée, avec notre hiérarchie, un arbre
arbre = new JTree();
this.model = new DefaultTreeModel(this.racine);
arbre.setModel(model);
arbre.setRootVisible(false);
arbre.setEditable(true);
arbre.getModel().addTreeModelListener(new TreeModelListener() {
public void treeNodesChanged(TreeModelEvent evt) {
}
public void treeNodesInserted(TreeModelEvent event) {
System.out.println("Un noeud a été inséré !");
}
public void treeNodesRemoved(TreeModelEvent event) {
System.out.println("Un noeud a été retiré !");
}
public void treeStructureChanged(TreeModelEvent event) {
System.out.println("La structure d'un noeud a changé !");
}
});
this.getContentPane().add(new JScrollPane(arbre), BorderLayout.CENTER);
}
private DefaultMutableTreeNode listFile(File file, DefaultMutableTreeNode node){
int count = 0;
if(file.isFile())
return new DefaultMutableTreeNode(file.getName());
else{
for(File nom : file.listFiles()){
count++;
//pas plus de 5 enfants par noeud
if(count < 3){
DefaultMutableTreeNode subNode;
if(nom.isDirectory()){
subNode = new DefaultMutableTreeNode(nom.getName()+"\\");
node.add(this.listFile(nom, subNode));
}else{
subNode = new DefaultMutableTreeNode(nom.getName());
}
node.add(subNode);
}
}
return node;
}
}
public static void main(String[] args){
//nous allons créer des fenêtres avec des looks différents
//Cette instruction permet de récupérer tous les looks du système
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (InstantiationException e) {
} catch (ClassNotFoundException e) {
} catch (UnsupportedLookAndFeelException e) {
} catch (IllegalAccessException e) {}
Fenetre fen = new Fenetre();
}
}
|
Ce qui me donne :
Avant toute suppression
Après suppression du dossier "Installer/"
Après suppression du dossier "D/"
Avant de clore ce chapitre, voici un petit cadeau.
Secret (cliquez pour afficher)
Voici comment utiliser un menu contextuel avec vos arbres.
Je n'ai implémenté qu'un menu contextuel pour effacer un noeud, mais la démarche est la même pour d'autres actions...
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221 | import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
public class Fenetre extends JFrame {
private JTree arbre;
private DefaultMutableTreeNode racine;
private DefaultTreeModel model;
private JButton bouton = new JButton("Ajouter"), effacer = new JButton("Effacer");
private JMenuItem eraseMenu ;
//On passe maintenant le nom du look and feel à utiliser en paramètre du constructeur
public Fenetre(){
this.setSize(200, 300);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("JTree");
//On invoque la méthode de construction de notre arbre
listRoot();
bouton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event) {
if(arbre.getLastSelectedPathComponent() != null){
JOptionPane jop = new JOptionPane();
String nodeName = jop.showInputDialog("Saisir un nom de noeud");
if(nodeName != null && !nodeName.trim().equals("")){
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)arbre.getLastSelectedPathComponent();
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(nodeName);
parentNode.add(childNode);
model.insertNodeInto(childNode, parentNode, parentNode.getChildCount()-1);
model.nodeChanged(parentNode);
}
}
else{
System.out.println("AUCUNE SELECTION ! ! !");
}
}
});
effacer.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event) {
if(arbre.getLastSelectedPathComponent() != null){
DefaultMutableTreeNode node = (DefaultMutableTreeNode)arbre.getLastSelectedPathComponent();
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)node.getParent();
model.removeNodeFromParent(node);
model.nodeChanged(parentNode);
}
else{
System.out.println("AUCUNE SELECTION ! ! !");
}
}
});
JPanel pan = new JPanel();
pan.add(bouton);
pan.add(effacer);
this.getContentPane().add(pan, BorderLayout.SOUTH);
this.setVisible(true);
}
private void listRoot(){
this.racine = new DefaultMutableTreeNode();
int count = 0;
for(File file : File.listRoots())
{
DefaultMutableTreeNode lecteur = new DefaultMutableTreeNode(file.getAbsolutePath());
try {
for(File nom : file.listFiles()){
DefaultMutableTreeNode node = new DefaultMutableTreeNode(nom.getName()+"\\");
lecteur.add(this.listFile(nom, node));
}
} catch (NullPointerException e) {}
this.racine.add(lecteur);
}
//On crée, avec notre hiérarchie, un arbre
arbre = new JTree();
this.model = new DefaultTreeModel(this.racine);
arbre.setModel(model);
arbre.setRootVisible(false);
arbre.setEditable(true);
arbre.getModel().addTreeModelListener(new TreeModelListener() {
public void treeNodesChanged(TreeModelEvent evt) {
}
public void treeNodesInserted(TreeModelEvent event) {
System.out.println("Un noeud a été inséré !");
}
public void treeNodesRemoved(TreeModelEvent event) {
System.out.println("Un noeud a été retiré !");
}
public void treeStructureChanged(TreeModelEvent event) {
System.out.println("La structure d'un noeud a changé !");
}
});
/**
* Effacer un noeud avec un menu contextuel ! !
*/
arbre.addMouseListener(new MouseAdapter(){
//Lorsque nous cliquons avec la souris
public void mousePressed(MouseEvent event) {
//Lors d'un clic droit
if(event.getButton() == MouseEvent.BUTTON3){
System.out.println("Clic droit détecté ! !");
//Si on a cliqué sur l'arbre, on peut récupérer l'indice de la ligne avec cette méthode
//Sinon, la méthode retourne -1
if(arbre.getRowForLocation(event.getX(), event.getY()) != -1){
//On peut récupérer le chemin du noeud qui a généré l'événement
arbre.setSelectionPath(arbre.getPathForLocation(event.getX(), event.getY()));
System.out.println("Noeud sélectionné : " + ((DefaultMutableTreeNode)arbre.getLastSelectedPathComponent()).toString());
//On peut donc en déduire le noeud et le parent
DefaultMutableTreeNode node = (DefaultMutableTreeNode)arbre.getLastSelectedPathComponent();
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)node.getParent();
//On n'a plus qu'à générer notre menu contextuel !
JPopupMenu jpm = new JPopupMenu();
eraseMenu = new JMenuItem("Effacer ce noeud");
eraseMenu.addActionListener(new EraseMenuListener(parentNode, node));
jpm.add(eraseMenu);
jpm.show(arbre, event.getX(), event.getY());
//Et le tour est joué ! ! !
}
}
}
});
this.getContentPane().add(new JScrollPane(arbre), BorderLayout.CENTER);
}
private DefaultMutableTreeNode listFile(File file, DefaultMutableTreeNode node){
int count = 0;
if(file.isFile())
return new DefaultMutableTreeNode(file.getName());
else{
for(File nom : file.listFiles()){
count++;
//pas plus de 5 enfants par noeud
if(count < 3){
DefaultMutableTreeNode subNode;
if(nom.isDirectory()){
subNode = new DefaultMutableTreeNode(nom.getName()+"\\");
node.add(this.listFile(nom, subNode));
}else{
subNode = new DefaultMutableTreeNode(nom.getName());
}
node.add(subNode);
}
}
return node;
}
}
/**
* Listener personnalisé pour le menu contextuel
* @author CHerby
*/
class EraseMenuListener implements ActionListener{
//Nous allons nous servir de ces deux objets
DefaultMutableTreeNode parentNode, node;
public EraseMenuListener(DefaultMutableTreeNode parent, DefaultMutableTreeNode node){
this.parentNode = parent;
this.node = node;
}
//Ici, vous connaissez !
public void actionPerformed(ActionEvent e) {
model.removeNodeFromParent(this.node);
model.nodeChanged(this.parentNode);
}
}
public static void main(String[] args){
//nous allons créer des fenêtres avec des looks différents
//Cette instruction permet de récupérer tous les looks du système
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (InstantiationException e) {
} catch (ClassNotFoundException e) {
} catch (UnsupportedLookAndFeelException e) {
} catch (IllegalAccessException e) {}
Fenetre fen = new Fenetre();
}
}
|
Le résultat est sympa :
Voilà : je pense que vous en savez assez pour utiliser les arbres dans vos futures applications !
Je vous propose donc un petit tour sur le topo des familles.