javaswingjtreetreecellrenderer

How to set Jtree node icon dynamically


I want to display separate icon for grouped and ungrouped nodes.I created a customTreeCellRender.My sample codes given below.In for loop odd one nodes have one icon and evens have another.But not change the icon of nodes.In my application ,populating tree nodes from db and grouping based on some conditions.This is a sample runnable code.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;

public class TestTree extends JDialog {

    JTree tree;

    DefaultTreeModel treeModel;

    public TestTree() {
        setSize(300, 800);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        System.out.println(getContentPane().getBackground());
    }

    protected static ImageIcon createImageIcon(String path) throws MalformedURLException {
        java.net.URL imgURL = new URL(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }

    public void init() throws MalformedURLException {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Numbers");
        treeModel = new DefaultTreeModel(root);
        tree = new JTree(treeModel);
        tree.setBackground(new Color(238, 238, 244));
        tree.setOpaque(true);

        CustomIconRenderer customIconRenderer = new CustomIconRenderer(true);
        customIconRenderer.setTextSelectionColor(Color.white);
        customIconRenderer.setBackgroundSelectionColor(Color.blue);
        customIconRenderer.setBorderSelectionColor(Color.black);
        customIconRenderer.setBackgroundNonSelectionColor(new Color(238, 238,
                244));
        ImageIcon icon = createImageIcon("https://i.sstatic.net/wCF8S.png");
        customIconRenderer.setLeafIcon(icon);


        for (int i = 0; i < 10; i++) {
            if (i % 2 == 0) {
                DefaultMutableTreeNode subroot = new DefaultMutableTreeNode(
                        "node_" + i);
                root.add(subroot);

                    tree.setCellRenderer(new CustomIconRenderer(false));

                if (i % 3 == 0) {
                    for (int j = 10; j < 15; j++) {
                        DefaultMutableTreeNode leaf = new DefaultMutableTreeNode(
                                "node_" + j);
                        subroot.add(leaf);
                    }
                }

            } else {
                DefaultMutableTreeNode subroot = new DefaultMutableTreeNode(
                        "node_" + i);
                root.add(subroot);
                tree.setCellRenderer(new CustomIconRenderer(true));
                if (i % 4 == 0) {
                    for (int j = 15; j < 20; j++) {
                        DefaultMutableTreeNode leaf = new DefaultMutableTreeNode(
                                "node_" + j);
                        subroot.add(leaf);
                    }

                }

            }
        }

        for (int i = 0; i < tree.getRowCount(); i++) {
            tree.expandRow(i);
        }

        tree.setCellRenderer(customIconRenderer);

        getContentPane().add(tree, BorderLayout.CENTER);
    }

    public static void main(String args[]) throws MalformedURLException {
        TestTree tt = new TestTree();
        tt.init();
        tt.setVisible(true);
    }
}
class CustomIconRenderer extends DefaultTreeCellRenderer {
    /**
     * 
     */
    private static final long serialVersionUID = 967937360839244309L;
    ImageIcon groupedIcon;
    ImageIcon unGroupedIcon;
    boolean grouped;

    public CustomIconRenderer() {

    }

    public CustomIconRenderer(boolean grouped) throws MalformedURLException {
        this.grouped = grouped;
        URL url=new URL("https://i.sstatic.net/wCF8S.png");
        URL url1=new URL("https://i.sstatic.net/T5uTa.png");
        groupedIcon = new ImageIcon(url1
                );
        unGroupedIcon = new ImageIcon(url
                );
    }
@Override
    public Component getTreeCellRendererComponent(JTree tree, Object value,
            boolean sel, boolean expanded, boolean leaf, int row,
            boolean hasFocus) {

        super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
                row, hasFocus);

        Object nodeObj = ((DefaultMutableTreeNode) value).getUserObject();
        // check whatever you need to on the node user object
        if (grouped) {
            setIcon(unGroupedIcon);
        } else {
            System.out.println("reached");
            setIcon(groupedIcon);
        }
        return this;
    }
}

Solution

  • There were a couple of mistakes in the original code, most notably:

    I think this is more along the lines of the requirement. Note that I was trying to stick as close to the original code as possible. I would approach this differently to how it is seen here.

    enter image description here

    import java.awt.*;
    import java.net.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    
    public class TestTree extends JDialog {
    
        JTree tree;
    
        DefaultTreeModel treeModel;
    
        public TestTree() {
            setSize(300, 800);
            setDefaultCloseOperation(DISPOSE_ON_CLOSE);
            System.out.println(getContentPane().getBackground());
        }
    
        protected static ImageIcon createImageIcon(String path) throws MalformedURLException {
            java.net.URL imgURL = new URL(path);
            if (imgURL != null) {
                return new ImageIcon(imgURL);
            } else {
                System.err.println("Couldn't find file: " + path);
                return null;
            }
        }
    
        public void init() throws MalformedURLException {
            DefaultMutableTreeNode root = new DefaultMutableTreeNode("Numbers");
            treeModel = new DefaultTreeModel(root);
            tree = new JTree(treeModel);
            tree.setBackground(new Color(238, 238, 244));
            tree.setOpaque(true);
    
            CustomIconRenderer customIconRenderer = new CustomIconRenderer();
            customIconRenderer.setTextSelectionColor(Color.white);
            customIconRenderer.setBackgroundSelectionColor(Color.blue);
            customIconRenderer.setBorderSelectionColor(Color.black);
            customIconRenderer.setBackgroundNonSelectionColor(new Color(238, 238,
                    244));
            ImageIcon icon = createImageIcon("https://i.sstatic.net/wCF8S.png");
            customIconRenderer.setLeafIcon(icon);
            tree.setCellRenderer(new CustomIconRenderer());
    
            for (int i = 0; i < 10; i++) {
                if (i % 2 == 0) {
                    DefaultMutableTreeNode subroot = new DefaultMutableTreeNode(
                            "node_" + i);
                    root.add(subroot);
    
                    if (i % 3 == 0) {
                        for (int j = 10; j < 15; j++) {
                            DefaultMutableTreeNode leaf = new DefaultMutableTreeNode(
                                    "node_" + j);
                            subroot.add(leaf);
                        }
                    }
                } else {
                    DefaultMutableTreeNode subroot = new DefaultMutableTreeNode(
                            "node_" + i);
                    root.add(subroot);
                    if (i % 4 == 0) {
                        for (int j = 15; j < 20; j++) {
                            DefaultMutableTreeNode leaf = new DefaultMutableTreeNode(
                                    "node_" + j);
                            subroot.add(leaf);
                        }
                    }
                }
            }
    
            for (int i = 0; i < tree.getRowCount(); i++) {
                tree.expandRow(i);
            }
    
            tree.setCellRenderer(customIconRenderer);
    
            getContentPane().add(tree, BorderLayout.CENTER);
        }
    
        public static void main(String args[]) throws MalformedURLException {
            TestTree tt = new TestTree();
            tt.init();
            tt.setVisible(true);
        }
    }
    
    class CustomIconRenderer extends DefaultTreeCellRenderer {
    
        /**
         *
         */
        private static final long serialVersionUID = 967937360839244309L;
        ImageIcon groupedIcon;
        ImageIcon unGroupedIcon;
    
        public CustomIconRenderer() throws MalformedURLException {
            URL url = new URL("https://i.sstatic.net/wCF8S.png");
            URL url1 = new URL("https://i.sstatic.net/T5uTa.png");
            groupedIcon = new ImageIcon(url1);
            unGroupedIcon = new ImageIcon(url);
        }
    
        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value,
                boolean sel, boolean expanded, boolean leaf, int row,
                boolean hasFocus) {
    
            super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
                    row, hasFocus);
    
            Object nodeObj = ((DefaultMutableTreeNode) value).getUserObject();
            String s = nodeObj.toString();
            System.out.println("s: " + s);
            boolean includesUnderscore = s.indexOf("_") > 0;
            if (includesUnderscore) {
                String lastPart = s.split("_")[1];
                int num = Integer.parseInt(lastPart);
                // check whatever you need to on the node user object
                if (num % 2 == 0) {
                    setIcon(unGroupedIcon);
                } else {
                    System.out.println("reached");
                    setIcon(groupedIcon);
                }
            }
            return this;
        }
    }