J'essaye de réaliser une structure arborescente JTree dont les 'UserObject's des 'DefaultMutableTreeNode's des 'leaf node's sont des JPanel plutôt que des String (càd pas d'appel de 'toString( )').

Dans mon application, le branchage est à 3 à 5 niveaux, le dernier de ces niveaux étant constitué d'un JPanel (feuilles) comportant ...
- une case d'affichage d'une valeur numérique (provenant de mon Array d'Object[] de valeurs initiales) modifiable,
- un bouton de "remise à la valeur originale",
- un libellé (JText) (provenant de mon Array d'Object[] de valeurs initiales),
- un Array de int multidimensionnel contenant la localisation dans mon Array d'Object[] de la cellule contenant la valeur numérique et le libellé initiaux à afficher dans ce JPanel
L'arborescence complète de référence est déterminée dans une Array d'Object[] multidimensionnelle instanciée au sein même de la classe et comporte notamment la valeur numérique et le libellé initiaux de chaque 'leaf node'. Cette arborescence sert de modèle pour la construction de l'arborescende de 'DefaultMutableTreeNode's.

Q1: Dans les tutoriaux consultés, je ne trouve qu'il manque un tableau récapitulatif indiquant ...
- quand il faut employer des 'MutableTreeNode's plutôt que des 'DefaultMutableTreeNode's, des 'TreeNode's plutôt que des 'MutableTreeNode's, et même pas de 'TreeNode' du tout (http://java.sun.com/docs/books/tutor...ents/tree.html --> § Creating a Data Model --> "... pre-existing hierarchical data structure, you do not need to duplicate it or force it into the TreeNode mold.")
- quand il faut employer des 'TreeModel' plutôt que 'MutableTreeModel'

Q2a: A la comparaison des Constructors, Methods et Fields (http://java.sun.com/javase/6/docs/api/javax/swing/tree/) est-il correct de déduire que 'DefaultMutableTreeNode' est nécessaire plutôt que 'MutableTreeNode' dès lors que l'application va avoir besoin de trouver des 'TreePath' permettant, à partir d'un noeud, de trouver le chemin pour arriver à un autre.
Q2b: Or ce serait mon cas : lorsque la fonction réentrante 'constructHiérarch' (= 'createNodes') construit une structure de 'DefaultMutableTreeNode's, c'est le bon moment de créer une table de référence de 'TreePath' entre cette structure de 'DefaultMutableTreeNode' et mon Array d'Object[] de valeurs initiales, de sorte que plus tard, lorsque sera activé le bouton (JButton) de "remise à la valeur originale" de la case d'affichage numérique (JTextField) d'un 'leaf node' (JPanel), la valeur numérique originale pourra être retrouvée dans mon Array d'Object[] et être replacée dans cette case d'affichage numérique.

Mon Array d'Object[] de valeurs initiales devrait donc approvisionner mon "public MyTreeModel extends DefaultTreeModel".

J'ai des problèmes pour que la programmation permette ...
- , lors de l'initialisation', de mettre les valeurs numériques originales dans la case d'affichage de la valeur (JTextField) ;
- , lors de l'activation du bouton de "remise à la valeur originale", de remettre la valeur originale dans la case d'affichage de la valeur.

A l'examen de la classe TreePath, j'observe ...
- que la localisation des noeuds est faite par un Array d'Object (à l'image de TreeModel) dont chaque Object comporte les String de chaque noeud. Il ne s'agit donc pas d'un Array d'indices numériques déterminant la localisation d'un noeud à partir de la racine.
Q3: Comment puis-je alors réaliser une table de référence entre l'arbre de 'DefaultMutableTreeNode's et mon Array d'Object[] de valeurs initiales (pour retrouver des valeurs originales dans mon Array d'Object[] sur base de la position retournée par le 'leaf node' sélectionné) ?
Q4: Puisque la classe TreePath ne me convient pas et que je dois construire moi-même une table de référence d'indices numériques de localisation de noeuds, cela constitue-t-il une raison pour me limiter à employer 'TreeNode' plutôt que 'DefaultMutableTreeNode' ?

Q5a: Qu'il faille construire une arborescence d'objets de classe 'DefaultMutableTreeNode', je le comprends. Mais pourquoi faut-il en plus re-établir une arborescence d'objet de classe 'DefaultTreeModel' ? Rien que pour avoir un objet sur base duquel on peut créer : " modèleArbre.addTreeModelListener(new MonGuêteur_ModèleArbre()); " ?
Q5b: La fonction 'getModel()' dans " modèleArbre = (DefaultTreeModel) arbre.getModel(); " permet d'obtenir un objet de classe 'TreeModel' à partir d'un arbre d'objets de classe 'DefaultTreeModel'. Existe-t-il une fonction inverse permettant d'obtenir un objet de classe 'DefaultTreeModel' à partir d'un arbre d'objets de classe 'TreeModel' ?

Dans mon Array d'Object[] de valeurs initiales, toutes les 'branch nodes' sont des Object[] et toutes 'leaf nodes' sont donc des objets de ma classe 'Feuille_ParamDroite', héritant de JPanel.
Par ailleur, le bon usage avec JTree veut que soit déclaré un objet de la classe 'TreeCellRenderer' :
TreeCellRenderer monRendu = new MonRendu_Feuille();
arbre.setCellRenderer(monRendu); // myRenderer
que l'arbre utilisera automatiquement pour tous les noeuds de type 'Feuille_ParamDroite' dans le 'TreeModel'.
Q6: Je ne comprends pas s'il y a double emploi ou bien quel lien il faut établir entre mes classes 'Feuille_ParamDroite' et 'monRendu_Feuille'.

Quelqu'un connaît-il un code source assez semblable qui fonctionne bien et pourrait m'inspirer ? ou a-t-il la patiente de me conseiller pour mon code ?

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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
 
import java.awt.*;                  // Container
import javax.swing.*;               // JPanel, JLabel
import javax.swing.event.TreeSelectionEvent;
import javax.swing.tree.*;          // DefaultMutableTreeNode
import javax.swing.event.TreeSelectionListener;
import java.math.BigDecimal;        // 
 
public class Les4PossCoffrBlocCompt extends JPanel implements TreeSelectionListener
{
    private Object[]               les4CombinaisPossBloCompt;
    public  JTree                  arbre;
    public  DefaultMutableTreeNode arborescenceNoeuds;
    private DefaultTreeModel       modèleArbre;
 
    public Les4PossCoffrBlocCompt(String nomDistributeur)
    {
        /* Sous-structure à imbriquer dans la structure principale.
        Object[] coûtsRegroupIdentTousTBK =
        {   
            new Object[]
            {   
                new Feuille_ParamDroite
                (   new BigDecimal(2.14233),    
                    "Coéfficient angulaire total"
                ),
                new Object[]
                {   "Contributions",
                    new Feuille_ParamDroite
                    (   new BigDecimal(0.673),
                        "Total des contributions"
                    ),
                    new Feuille_ParamDroite
                    (   new BigDecimal(0.162),
                        "Cogénération"
                    )
                },
                new Object[]
                {   "Suppléments",
                    new Feuille_ParamDroite
                    (   new BigDecimal(0.49933),
                        "Total des suppléments"
                    ),
                    new Object[]
                    {   "Cotisations",
                        new Feuille_ParamDroite
                        (   new BigDecimal(0.49933),
                            "Total des cotisations"
                        ),
                        new Feuille_ParamDroite
                        (   new BigDecimal(0.26837),
                            "Cotisation fédérale"
                        ),
                        new Feuille_ParamDroite
                        (   new BigDecimal(0.00),
                            "Cotisation pour les communes"
                        )
                    },
                    new Object[]
                    {   "Redevances",
                        new Feuille_ParamDroite
                        (   new BigDecimal(0.00),
                            "Total des redevances"
                        ),
                        new Feuille_ParamDroite
                        (   new BigDecimal(0.00),
                            "Redevance voirie"
                        ),
                        new Feuille_ParamDroite
                        (   new BigDecimal(0.00),
                            "Redevance raccordement"
                        )
                    }
                }
            }
        };
    
        //   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
        /* Structure principale
         * Il y a en fait 47 root et branch nodes et 100 leaf nodes au total.
         */
        this.les4CombinaisPossBloCompt = new Object[]
        {   nomDistributeur,
            new Object[]
            {   "<html>Coffret à un seul bloc de compteur(s)",
                new Object[]
                {   "Coûts fixes propres à ce compteur",
                    new Feuille_ParamDroite
                    (   new BigDecimal(91.65),
                        "Total"
                    ),
                    new Feuille_ParamDroite
                    (   new BigDecimal(9.87),
                        "Location du bloc de compteur(s)"
                    )
                },
                {   "Coûts f(consommation) propres à ce compteur",
                    new Feuille_ParamDroite
                    (   new BigDecimal(18.70),
                        "Coéfficient angulaire total"
                    ),
                    new Feuille_ParamDroite
                    (   new BigDecimal(9.56),
                        "Distribution - C. normal"
                    )
                },
                coûtsRegroupIdentTousTBK[0]
            },
            new Object[]
            {   "<html>Coffret à un seul bloc de compteur(s)",
                new Object[]
                {   "Bi-horaire",
                    new Object[]
                    {   "Bi-horaire - jour",
                        new Object[]
                        {   "Coûts fixes propres à ce compteur",
                            new Feuille_ParamDroite
                            (   new BigDecimal(122.11),
                                "Total"
                            ),
                            new Feuille_ParamDroite
                            (   new BigDecimal(9.87),
                                "Location du bloc de compteur(s)"
                            )
                        },
                        new Object[]
                        {   "Coûts f(consommation)",
                            new Feuille_ParamDroite
                            (   new BigDecimal(19.96),
                                "Coéfficient angulaire total"
                            ),
                            new Feuille_ParamDroite
                            (   new BigDecimal(9.56),
                                "Distribution - C. bihoraire - h. pleines"
                            )
                        }
                    },
                    new Object[]
                    {   "Bi-horaire - nuit",
                        new Object[]
                        {   "Coûts fixes propres à ce compteur",
                            new Feuille_ParamDroite
                            (   new BigDecimal(0.00),
                                "Total - en €/an"
                            ),
                            new Feuille_ParamDroite
                            (   new BigDecimal(0.00),
                                "Location du bloc de compteur(s)"
                            )
                        },
                        new Object[]
                        {   "Coûts f(consommation) propres à ce compteur",
                            new Feuille_ParamDroite
                            (   new BigDecimal(11.97),
                                "Coéfficient angulaire total"
                            ),
                            new Feuille_ParamDroite
                            (   new BigDecimal(6.52),
                                "Distribution - C. bi-horaire - h. creuses"
                            )
                        }
                    }
                },
                coûtsRegroupIdentTousTBK[0]
            },
            new Object[]
            {   "<html>Coffret à deux blocs de compteur(s)",
                new Object[]
                {   "Coûts f(consommation) propres à ce compteur",
                    new Feuille_ParamDroite
                    (   new BigDecimal(18.70),
                        "Coéfficient angulaire total"
                    ),
                    new Feuille_ParamDroite
                    (   new BigDecimal(9.56),
                        "Distribution - C. normal"
                    )
                },
                new Object[]
                {   "Bloc à compteur nuit exclusiv.t - Coûts fixes",
                    new Feuille_ParamDroite
                    (   new BigDecimal(9.87),
                        "Total"
                    ),
                    new Feuille_ParamDroite
                    (   new BigDecimal(9.87),
                        "Location du bloc de compteur(s)"
                    )
                },
                new Object[]
                {   "Coûts f(consommation) propres à ce compteur",
                    new Feuille_ParamDroite
                    (   new BigDecimal(9.31),
                        "Coéfficient angulaire total"
                    ),
                    new Feuille_ParamDroite
                    (   new BigDecimal(4.62),
                        "Distribution - C. normal"
                    )
                },
                coûtsRegroupIdentTousTBK[0]
            },
            new Object[]
            {   "<html>Coffret à deux blocs de compteur(s)",
                new Object[]
                {   "Bi-horaire",
                    new Object[]
                    {   "Bi-horaire - jour",
                        new Object[]
                        {   "Coûts fixes propres à ce compteur",
                            new Feuille_ParamDroite
                            (   new BigDecimal(122.11),
                                "Total"
                            ),
                            new Feuille_ParamDroite
                            (   new BigDecimal(9.87),
                                "Location du bloc de compteur(s)"
                            )
                        }
                    },
                    new Object[]
                    {   "Bi-horaire - nuit",
                        new Object[]
                        {   "Coûts fixes propres à ce compteur",
                            new Feuille_ParamDroite
                            (   new BigDecimal(0.00),
                                "Total - en €/an"
                            ),
                            new Feuille_ParamDroite
                            (   new BigDecimal(0.00),
                                "Location du bloc de compteur(s)"
                            )
                        }
                    }
                },
                new Object[]
                {   "Bloc à compteur nuit exclusiv.t - Coûts fixes",
                    new Feuille_ParamDroite
                    (   new BigDecimal(9.87),
                        "Total"
                    ),
                    new Feuille_ParamDroite
                    (   new BigDecimal(9.87),
                        "Location du bloc de compteur(s)"
                    )
                }
                coûtsRegroupIdentTousTBK[0]
            }
        };
 
        /* Le constructeur hiérarchique
         * - construit la structure arborescence des branches et des noeuds ou feuilles,
         * - crée les branchettes et les feuilles et remplit les valeurs originales
         *   de celles-ci.
         */
        // DefaultMutableTreeNode
        arborescenceNoeuds = constructHiérarch(les4CombinaisPossBloCompt);
 
        arbre = new JTree(arborescenceNoeuds);
        this.add(arbre, BorderLayout.CENTER);
 
        // modèleArbre = new DefaultTreeModel(arborescenceNoeuds);
        modèleArbre = (DefaultTreeModel) arbre.getModel();
        // modèleArbre.addTreeModelListener(new MonGuêteur_ModèleArbre());
 
        arbre.getSelectionModel().
                setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
 
        arbre.addTreeSelectionListener(this);
 
        // TreePath brancheSélectionnée = new TreePath(getPath(de4MogelTBKasten[2]));
        arbre.putClientProperty("JTree.lineStyle", "Horizontal");
 
        TreeCellRenderer monRendu = new MonRendu_Feuille();
        arbre.setCellRenderer(monRendu);     // myRenderer
    }
 
 
    /** Small routine that will make a header node out of the first entry in the 
     *  array, then make nodes out of subsequent entries and make them kind nodes
     *  of the first one. The process is repeated recursively for entries that
     *  are arrays.
     *  Il y a en fait 47 root et branch nodes et 100 leaf nodes au total.
     */
    private DefaultMutableTreeNode constructHiérarch(Object[] de4MogelCombinVanTellers)
    {   DefaultMutableTreeNode hoofdKnoop =
                    new DefaultMutableTreeNode(de4MogelCombinVanTellers[0]);
        DefaultMutableTreeNode kind;
 
        for (int i = 1; i < de4MogelCombinVanTellers.length; i++)
        {	Object nodeSpecifier = de4MogelCombinVanTellers[i];
            if (nodeSpecifier instanceof Object[])  // Branch node (with children)
            {	// Re-entering the function
                // 'kind' devient le 'hoofdKnoop' dans la fonction ré-entrée.
                kind = constructHiérarch((Object[]) nodeSpecifier);
            } else 
            {	if (nodeSpecifier instanceof Feuille_ParamDroite) // Node = leaf
				{	kind = new DefaultMutableTreeNode(nodeSpecifier);
                   /* Problème : Une 'Feuille_ParamDroite' peut se trouver au
                    * niveau 2, 3 ou 4 d'indentation.   */
                   /* System.out.printf("%01d => %.2f - %s\n", i,
                        ((Feuille_ParamDroite) nodeSpecifier).getTotal(),
                        ((Feuille_ParamDroite) nodeSpecifier).getLibellé() );
                    */
                   /* Dans la phase précédant 'constructHiérarch()', a eu lieu
                    * la déclaration de l'Array 'les4CombinaisPossBloCompt'
                    * ainsi que son initialisation, c à d aussi l'implémentation
                    * de tous les objets de la classe 'Feuille_ParamDroites'.
                    * Chacun de ceux-ci doit à présent être associé
                    * - à l'objet 'kind' créé un à un ici-même;
                    * - à l'objet 'Feuille_ParamDroites' qui crée le panneau à
                    * afficher et initialise les champs (valeur et libellé).
                    */
                    // System.out.printf("%[s]\n", (Object[])kind.getPath());
                    System.out.printf("%s\n", kind.getUserObjectPath() );
 
 
                } else                              // Node = String ?
                {	kind = null;
                }
            }
            hoofdKnoop.add(kind);   // Une 'branch node' ou une feuille.
        }
        return (hoofdKnoop);
    }
 
 
    /* Returns the last path element of the selection.
     * This method is useful only when the selection model allows a single selection.
     */
    @Override public void valueChanged(TreeSelectionEvent e)
    {
        DefaultMutableTreeNode noeudSélectionné =
                (DefaultMutableTreeNode) arbre.getLastSelectedPathComponent();
        Object objetDuNoeudSélectionné = null;
 
        // saySomething("Un nouveau noeud est sélectionné", e);
 
        if (noeudSélectionné == null)       // Aucun noeud n'est sélectionné
        {   return;
        }
 
        if (noeudSélectionné.isLeaf())
        {   Feuille_ParamDroite feuille_ParamDroite =
                               (Feuille_ParamDroite)objetDuNoeudSélectionné;
            objetDuNoeudSélectionné = noeudSélectionné.getUserObject();
        }
    }
 
 
    /* Méthode appelée par
     * - le constructeur de la classe 'MultiPaneFrame',
     *      là où l'arbre est construit : Onglet2
     */
    public JPanel get_ArbreComposParamDr()
    {   return this;
    }
}
...
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
 
class Feuille_ParamDroite  extends MonRendu_Feuille     // extends JPanel
{
    BigDecimal total;
    String     libelléParamDroite;
    short[]    indicesNumChemin;
 
    /** Creates a new instance of Feuille_ParamDroite */
    public Feuille_ParamDroite(BigDecimal totaal, String naam_RechteParam)
    {	this.total = totaal;
        this.libelléParamDroite = new String(naam_RechteParam);
    }
 
    BigDecimal getTotal()
    {	return total;
    }
 
    String getLibellé()
    {	return libelléParamDroite;
    }
}
...
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
 
import java.awt.Component;
import java.awt.Color;
 
import javax.swing.JPanel;
import javax.swing.JTree;           // getTreeCellRendererComponent(JTree tree
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.BorderFactory;
 
 
/**
 *  Create my own TreeCellRenderer implementation from scratch to use 
 *  whatever components (JPanel).
 *  If use of JLabel : DefaultTreeCellRenderer = a subclass of JLabel.
 */
public class MonRendu_Feuille extends JPanel implements TreeCellRenderer
{
    private javax.swing.JFormattedTextField valeur;
    private javax.swing.JButton             remiseàLaValeurOfficielle_b;
    private javax.swing.JLabel              libelléParamDroite;
 
    private DefaultTreeCellRenderer renduParDéfaut = new DefaultTreeCellRenderer();
    private Color                   coulArr_Sélectionné;
    private Color                   coulArr_NonSélectionné;
 
 
    MonRendu_Feuille()
    {   
        valeur                      = new javax.swing.JFormattedTextField();
        remiseàLaValeurOfficielle_b = new javax.swing.JButton("reset");
        libelléParamDroite          = new javax.swing.JLabel();
 
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
 
        layout.setHorizontalGroup
        (   layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup
            (layout.createSequentialGroup()
                    // Class GroupLayout.Group. To explicitly specify the range
                    // The minimum is explicitly specified as 30, preferred as 50, and maximum as 70.
                .addComponent(valeur,
                              30, // javax.swing.GroupLayout.PREFERRED_SIZE,
                              50, // javax.swing.GroupLayout.DEFAULT_SIZE,
                              70  // javax.swing.GroupLayout.PREFERRED_SIZE
                             )
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(remiseàLaValeurOfficielle_b,
                              javax.swing.GroupLayout.PREFERRED_SIZE,
                              25,
                              javax.swing.GroupLayout.PREFERRED_SIZE
                             )
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(libelléParamDroite,
                              javax.swing.GroupLayout.PREFERRED_SIZE,
                              246,
                              javax.swing.GroupLayout.PREFERRED_SIZE
                             )
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE,
                                 Short.MAX_VALUE
                                )
            )
        );
 
        layout.setVerticalGroup
        (
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.
                createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(valeur,
                              javax.swing.GroupLayout.PREFERRED_SIZE,
                              javax.swing.GroupLayout.DEFAULT_SIZE,
                              javax.swing.GroupLayout.PREFERRED_SIZE
                             )
                .addComponent(remiseàLaValeurOfficielle_b,
                              javax.swing.GroupLayout.PREFERRED_SIZE,
                              18,   // javax.swing.GroupLayout.DEFAULT_SIZE,
                              javax.swing.GroupLayout.PREFERRED_SIZE
                             )
                .addComponent(libelléParamDroite)
                     )
        );
 
        this.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
        coulArr_Sélectionné    = renduParDéfaut.getBackgroundSelectionColor();
        coulArr_NonSélectionné = renduParDéfaut.getBackgroundNonSelectionColor();
 
    }
 
 
    /* JTree, by default, renders each node using the value returned from toString().
    public String toString()
    {   return libelléItem;
    }
    */
 
 
    @Override
    public Component getTreeCellRendererComponent(JTree arbre, Object value,
                                       /* Feuille_ParamDroites value, */
                                        boolean selected, boolean expanded, 
                                        boolean leaf, int row, boolean hasFocus
                                                 )
    {   Component valeurARetourner = null;
 
        if ( (value != null) &&
             (value instanceof DefaultMutableTreeNode)
           )
        {
          Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
 
          if (userObject instanceof Feuille_ParamDroite)
          {
            Feuille_ParamDroite panneauFeuille_ParamDroite =
                                            (Feuille_ParamDroite) userObject;
 
//            valeur.setText(toString(panneauFeuille_ParamDroite.getTotal()));
 
            remiseàLaValeurOfficielle_b.setText("V 0");            // Valeur officielle
 
            libelléParamDroite.setText(panneauFeuille_ParamDroite.getLibellé());
 
            if (selected)
            {           // this = monRendu
              this.setBackground(coulArr_Sélectionné);
            } else
            {
              this.setBackground(coulArr_NonSélectionné);
            }
            this.setEnabled(arbre.isEnabled());
            valeurARetourner = this;
          }
        }
 
        if (valeurARetourner == null)
        {
          valeurARetourner = renduParDéfaut.getTreeCellRendererComponent(arbre,
              value, selected, expanded, leaf, row, hasFocus);
        }
        return valeurARetourner;
   }
}
Merci d'essayer de m'aider.