3

I have a JTree, based on several custom classes. I want to give several Nodes a specific icon. Therefore i did the following code based on this link: Dynamically change icon of specific nodes in JTree

        DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer() {
        private static final long serialVersionUID = 1L;
        private Icon good = new ImageIcon(getClass().getResource("/good.png"));
        private Icon dunno = new ImageIcon(getClass().getResource("/dunno.png"));
        private Icon bad = new ImageIcon(getClass().getResource("/bad.png"));

        @Override
        public Component getTreeCellRendererComponent(JTree tree,
            Object value, boolean selected, boolean expanded,
            boolean isLeaf, int row, boolean focused) {

            Component c = super.getTreeCellRendererComponent(tree, value, selected, expanded, isLeaf, row, focused);

            // JTreePanelNode node = (JTreePanelNode)c; - not possible
            return c;
        }
    };
    this.getTree().setCellRenderer(renderer);   

Each of my Nodes is an object of JTreePanelNode (custom class), which saves a specific state which can be set via setState(String s) and get via getState(). So what i want is to something like this:

if(node.getState().equals("good")) ..
else if(node.getState.equals("bad")) ..
else ..

How can i achieve something like that? From what i understand the renderer goes through every node with getTreeCellRendererComponent and applies a specific icon which i can choose with setIcon and several ifs(). However i cannot cast to JTreePanelNode. Any solution? Thanks :)

Community
  • 1
  • 1

2 Answers2

3

All depends on your JTreePanelNode Class. if it implements the TreeNode interface you are good to go with:

public Component getTreeCellRendererComponent(JTree tree, Object value,
        boolean sel, boolean expanded, boolean leaf, int row,
        boolean hasFocus) {
    Component comp = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
            row, hasFocus);
    TreeNode current = (TreeNode)value;

    if (leaf) {
        //set leaf icon
    } else if (expanded) {
        //set expanded icon
    } else {
        // set default state
    }

    if (hasFocus)
        //set what it looks like if focused

    else if (selected)
        //set what it looks like if selected

    else
        //set default l&f

    comp.setIcon(whatevericonset in above conditions);

    return comp;
}

Of course you can add many more states depending on your node class.getState().

gantners
  • 471
  • 4
  • 16
2

you can get access to the Object represented in that tree:

@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean isLeaf, int row, boolean focused) {

    Component c = super.getTreeCellRendererComponent(tree, value, selected, expanded, isLeaf, row, focused);
    DefaultMutableTreeNode node = (DefaultMutableTreeNode ) value;
    Object representedObject = node.getUserObject();

    JLabel superLabel = super.getTreeCellRendererComponent();
    String text = label.getText();

    if(object.isGood() ){ //i don't know your code
        superLabel .setText (text +"goooooooood");
    }else{
        superLabel .setText (text +"badbadbabd");
    }
    return superLabel ;
}
Martin Frank
  • 3,445
  • 1
  • 27
  • 47
  • 1
    While technically correct, this does assume a particular implementation. What if the OP is not using `DefaultMutableTreeNode`? – MadProgrammer Aug 29 '14 at 11:46
  • hehehe - yes, you are very right and a good observer!! i'm deeply impressed!! i assume that user follow the trail on http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html... but i cannot guarantee that!! very observative, keep up that good work =) – Martin Frank Aug 29 '14 at 11:51
  • 1
    Well, you might get lucky ;) – MadProgrammer Aug 29 '14 at 11:51
  • Thanks a lot guys. I didn't realize that "value" is the node representation which i can cast back to my own class. –  Aug 29 '14 at 14:08