Modifiez la valeur de ce champ et repeignez le JTree.
class CustomTreeCellRenderer extends DefaultTreeCellRenderer{
ImageIcon rendererIcon;
public void setRendererIcon(ImageIcon myIcon){
this.rendererIcon = myIcon;
};
public Component getTreeCellRendererComponent(JTree tree,
Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus){
super.getTreeCellRendererComponent(tree, value,
selected, expanded, leaf, row, hasFocus);
JLabel label = (JLabel) this ;
label.setIcon(rendererIcon) ;
return this;
}
}
Edit: explications
Dans votre cas, il est inutile de changer le modèle. L'icône utilisée pour afficher chacun des nœuds fait partie du moteur de rendu.
L'objet de rendu du JTree n'est pas obligatoirement un JComponent
. Il doit être un objet fournissant un JComponent
lorsque le code appelle getTreeCellRendererComponent
.
Dans votre cas, la conversion de getCellRenderer() en JLabel est simplement une chance car l'implémentation par défaut du DefaultTreeCellRenderer
est une extension de JLabel
. Et, en fait, comme votre moteur de rendu a appelé setIcon sur lui-même, il est normal que vos méthodes getIcon vous donnent la dernière icône que vous avez placée dans le moteur de rendu.
Code de travail complet:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultTreeCellRenderer;
public class TestJTree {
private static ImageIcon iconWhite = new ImageIcon("white.jpg");
private static ImageIcon iconBlack = new ImageIcon("black.jpg");;
public static void main(String[] args) {
TestJTree me = new TestJTree();
me.process();
}
private void process() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
initGui();
}
});
}
protected void initGui() {
JFrame frame = new JFrame("Test JTree");
frame.setContentPane(new JPanel(new BorderLayout()));
final JTree tree = new JTree();
frame.getContentPane().add(tree);
final CustomTreeCellRenderer renderer = new CustomTreeCellRenderer();
renderer.setRendererIcon(iconWhite);
tree.setCellRenderer(renderer);
JPanel panelButtons = new JPanel();
JButton buttonWhite = new JButton("");
buttonWhite.setIcon(iconWhite);
JButton buttonBlack = new JButton("");
buttonBlack.setIcon(iconBlack);
buttonBlack.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
renderer.setRendererIcon(iconBlack);
tree.repaint();
}
});
panelButtons.add(buttonBlack);
panelButtons.add(buttonWhite);
frame.getContentPane().add(panelButtons,BorderLayout.SOUTH);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setVisible(true);
}
@SuppressWarnings("serial")
private static class CustomTreeCellRenderer extends DefaultTreeCellRenderer{
ImageIcon rendererIcon;
public void setRendererIcon(ImageIcon myIcon){
this.rendererIcon = myIcon;
};
public Component getTreeCellRendererComponent(JTree tree,
Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus){
Component ret = super.getTreeCellRendererComponent(tree, value,
selected, expanded, leaf, row, hasFocus);
JLabel label = (JLabel) ret ;
label.setIcon(rendererIcon) ;
return ret;
}
}
}
J'ai essayé, mais cela ne fonctionne pas. – mogli
@rits Le code que j'ai ajouté fonctionne pour moi –
Oui, l'icône change pour l'ensemble de l'arborescence, pas pour le nœud sélectionné. – mogli