How do I create JTree with different icons for each node?

The example below demonstrates you how to create a JTree that have a different icons for each node of the tree.

package org.kodejava.example.swing;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeCellRenderer;
import java.awt.*;
import java.net.URL;

public class JTreeDifferentNodeIcon extends JFrame {
    public JTreeDifferentNodeIcon() throws HeadlessException {
        initializeUI();
    }

    private void initializeUI() {
        setSize(200, 400);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Countries");
        DefaultMutableTreeNode asia = new DefaultMutableTreeNode("Asia");
        Country[] countries = new Country[]{
                new Country("India", "/flags/in.png"),
                new Country("Singapore", "/flags/sg.png"),
                new Country("Indonesia", "/flags/id.png"),
                new Country("Vietnam", "/flags/vn.png"),
        };

        for (Country country : countries) {
            DefaultMutableTreeNode node = new DefaultMutableTreeNode(country);
            asia.add(node);
        }

        DefaultMutableTreeNode northAmerica = new DefaultMutableTreeNode("North America");
        countries = new Country[]{
                new Country("United States", "/flags/us.png"),
                new Country("Canada", "/flags/ca.png")
        };

        for (Country country : countries) {
            DefaultMutableTreeNode node = new DefaultMutableTreeNode(country);
            northAmerica.add(node);
        }

        DefaultMutableTreeNode southAmerica = new DefaultMutableTreeNode("South America");
        countries = new Country[]{
                new Country("Brazil", "/flags/br.png"),
                new Country("Argentina", "/flags/ar.png"),
                new Country("Uruguay", "/flags/uy.png")
        };
        for (Country country : countries) {
            DefaultMutableTreeNode node = new DefaultMutableTreeNode(country);
            southAmerica.add(node);
        }

        DefaultMutableTreeNode europe = new DefaultMutableTreeNode("Europe");
        countries = new Country[]{
                new Country("United Kingdom", "/flags/gb.png"),
                new Country("Germany", "/flags/de.png"),
                new Country("Spain", "/flags/es.png"),
                new Country("France", "/flags/fr.png"),
                new Country("Italy", "/flags/it.png")
        };
        for (Country country : countries) {
            DefaultMutableTreeNode node = new DefaultMutableTreeNode(country);
            europe.add(node);
        }

        root.add(asia);
        root.add(northAmerica);
        root.add(southAmerica);
        root.add(europe);

        final JTree tree = new JTree(root);
        tree.setCellRenderer(new CountryTreeCellRenderer());

        JScrollPane pane = new JScrollPane(tree);
        pane.setPreferredSize(new Dimension(200, 400));

        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(pane, BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new JTreeDifferentNodeIcon().setVisible(true);
            }
        });
    }

    class CountryTreeCellRenderer implements TreeCellRenderer {
        private JLabel label;

        CountryTreeCellRenderer() {
            label = new JLabel();
        }

        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded,
                                                      boolean leaf, int row, boolean hasFocus) {
            Object o = ((DefaultMutableTreeNode) value).getUserObject();
            if (o instanceof Country) {
                Country country = (Country) o;
                URL imageUrl = getClass().getResource(country.getFlagIcon());
                if (imageUrl != null) {
                    label.setIcon(new ImageIcon(imageUrl));
                }
                label.setText(country.getName());
            } else {
                label.setIcon(null);
                label.setText("" + value);
            }
            return label;
        }
    }

    class Country {
        private String name;
        private String flagIcon;

        Country(String name, String flagIcon) {
            this.name = name;
            this.flagIcon = flagIcon;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getFlagIcon() {
            return flagIcon;
        }

        public void setFlagIcon(String flagIcon) {
            this.flagIcon = flagIcon;
        }
    }
}

Here is the result of our program above:

JTree Nodes with Icon

Flag icons provided by FamFamFam Flag Icons.

Wayan

Programmer, runner, recreational diver, live in the island of Bali, Indonesia. Mostly programming in Java, Spring Framework, Hibernate / JPA.

5 Comments

  1. Hi Hades,

    If the imageUrl is null it means that it cannot find the flags icon. You need to place the icon under the resources directory.

    ├── pom.xml
    └── src
        └── main
            ├── java
            │   └── org
            │       └── kodejava
            │           └── example
            │               └── swing
            │                   └── JTreeDifferentNodeIcon.java
            └── resources
                └── flags
                    ├── ar.png
                    ├── br.png
    
    Reply
    • Hi Doug,

      You can add the following snippet if you want to make the JTree node selectable.

      tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
      tree.addTreeSelectionListener(new TreeSelectionListener() {
          @Override
          public void valueChanged(TreeSelectionEvent e) {
              DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
              if (node == null) {
                  return;
              }
      
              Object nodeInfo = node.getUserObject();
              if (node.isLeaf()) {
                  Country country = (Country) nodeInfo;
                  System.out.println("country = " + country.getName());
              }
          }
      });
      

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.