Bonjour,

J'essaie de réaliser un Jtree dynamique en m'inspirant très largement de l'exemple de la doc ici et ici.

Voici ma classe :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
public class ApplicationsPanel extends JPanel implements LanguageRefreshable, ActionListener, TreeSelectionListener
{
	private static final long serialVersionUID = 1L;
 
	/**************************************************
         * ATTRIBUTS
         **************************************************/
 
	private JTree appTree;
	private DefaultMutableTreeNode rootNode;
	private DefaultTreeModel treeModel;
 
	private MyCustomNode customNode;
	private int nodeIndex = 0;
 
	private static String ADD_COMMAND = "add";
	private static String REMOVE_COMMAND = "remove";
	private static String CLEAR_COMMAND = "clear";
 
	/**************************************************
         * CONSTRUCTEUR
         **************************************************/
 
	public ApplicationsPanel()
	{
		super();
 
		initGUI();
	}
 
	/**************************************************
         * INITIALISATION DES COMPOSANTS
         **************************************************/
 
	private void initGUI()
	{
		final GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[] { 0 };
		gridBagLayout.rowHeights = new int[] { 0, 0 };
		gridBagLayout.columnWeights = new double[] { 1.0 };
		gridBagLayout.rowWeights = new double[] { 1.0, 0.0 };
		setLayout(gridBagLayout);
 
		final JButton addButton = new JButton("Add");
		addButton.setActionCommand(ADD_COMMAND);
		addButton.addActionListener(this);
 
		final JButton removeButton = new JButton("Remove");
		removeButton.setActionCommand(REMOVE_COMMAND);
		removeButton.addActionListener(this);
 
		final JButton clearButton = new JButton("Clear");
		clearButton.setActionCommand(CLEAR_COMMAND);
		clearButton.addActionListener(this);
 
		final JPanel panel = new JPanel(new GridLayout(0, 3));
		panel.add(addButton);
		panel.add(removeButton);
		panel.add(clearButton);
		add(panel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
 
		rootNode = new DefaultMutableTreeNode("root");
		populateTree(rootNode);
		treeModel = new DefaultTreeModel(rootNode);
 
		appTree = new JTree(rootNode);
		appTree.setRootVisible(true);
		appTree.setShowsRootHandles(true);
		appTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
		appTree.addTreeSelectionListener(this);
 
		// Creation d'un panneau deroulant qui va contenir l'arbre des applications
		final JScrollPane treeView = new JScrollPane(appTree);
		add(treeView, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
	}
 
	/**************************************************
         * METHODES INTERNES
         **************************************************/
 
	private void populateTree(final DefaultMutableTreeNode top)
	{
		customNode = new MyCustomNode();
		final DefaultMutableTreeNode app = new DefaultMutableTreeNode(customNode );
		top.add(app);
	}
 
	/**************************************************
         * GESTION DES NOEUDS
         **************************************************/
 
	/** Remove all nodes except the root node. */
	public void clear()
	{
		rootNode.removeAllChildren();
		treeModel.reload();
	}
 
	/** Remove the currently selected node. */
	public void removeCurrentNode()
	{
		final TreePath currentSelection = appTree.getSelectionPath();
		if (currentSelection != null)
		{
			final DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)(currentSelection.getLastPathComponent());
			final MutableTreeNode parent = (MutableTreeNode)(currentNode.getParent());
			if (parent != null)
			{
				treeModel.removeNodeFromParent(currentNode);
				return;
			}
		}
		// Si pas de noeud selectionné on ne fait rien
	}
 
	/**
         * Ajoute un fils au noeud sélectionné
         */
	public DefaultMutableTreeNode addObject(final Object child)
	{
		DefaultMutableTreeNode parentNode = null;
		final TreePath parentPath = appTree.getSelectionPath();
 
		if (parentPath == null)
		{
			parentNode = rootNode;
		}
		else
		{
			parentNode = (DefaultMutableTreeNode)(parentPath.getLastPathComponent());
		}
 
		return addObject(parentNode, child, true);
	}
 
	public DefaultMutableTreeNode addObject(final DefaultMutableTreeNode parent, final Object child)
	{
		return addObject(parent, child, false);
	}
 
	public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent, final Object child, final boolean shouldBeVisible)
	{
		final DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(child);
 
		if (parent == null)
		{
			parent = rootNode;
		}
 
		//It is key to invoke this on the TreeModel, and NOT DefaultMutableTreeNode
		treeModel.insertNodeInto(childNode, parent, parent.getChildCount());
 
		//Make sure the user can see the new node.
		if (shouldBeVisible)
		{
			appTree.scrollPathToVisible(new TreePath(childNode.getPath()));
		}
 
		return childNode;
	}
 
	/**************************************************
         * GESTION DES EVENEMENTS
         **************************************************/
 
	@Override
	public void actionPerformed(final ActionEvent e)
	{
		final String command = e.getActionCommand();
 
		if (ADD_COMMAND.equals(command))
		{
			//Add button clicked
			addObject("New Node " + nodeIndex++);
		}
		else if (REMOVE_COMMAND.equals(command))
		{
			//Remove button clicked
			removeCurrentNode();
		}
		else if (CLEAR_COMMAND.equals(command))
		{
			//Clear button clicked.
			clear();
		}
		treeModel.reload();
	}
 
	@Override
	public void refreshLanguage()
	{
		// TODO Auto-generated method stub
 
	}
 
	@Override
	public void valueChanged(final TreeSelectionEvent e)
	{
		// TODO Auto-generated method stub
 
	}
}
La seule différence entre ma classe et l'exemple vient de la méthode "actionPerformed" que j'ai choisi de gerer en interne.
Donc quand je selectionne un noeud et que je clic sur "add" le premier fils est ajouté et affiché.
Le soucis c'est que quand je clic a nouveau sur le bouton "add" en ayant le même nœud parent sélectionné les autres fils ne sont pas affichés alors qu'ils sont bien ajoutés dans le treeModel (Debuggeur à l'appui)
Alors que avec l'exemple les nœuds s'ajoutent et sont affichés correctement.

Ai-je fait une erreur dans mon code? ou le problème viendrait- il d'autre chose?

Quelques images pour illustrer ma question
Arbre initial :
Nom : tree0.jpg
Affichages : 825
Taille : 15,0 Ko

Je sélectionne le noeud et je clic sur add 1 fois :
Nom : tree1.jpg
Affichages : 837
Taille : 17,4 Ko

JE clic 10 fois sur add sans changer la selection puis je selectione le noeud 0 et je clic sur add
Nom : tree3.jpg
Affichages : 844
Taille : 19,1 Ko

Le treeModel :
Nom : treeModel.jpg
Affichages : 883
Taille : 75,6 Ko


Merci de votre aide