Close

JTree - Creating JTree From YAML data

[Last Updated: Jul 4, 2018]

Following example provides a generic utility to load YAML data and build TreeNode from it. We are going to use SnakeYAML implementation to load data from yml file.

Building TreeNode from YAML

package com.logicbig.uicommon;

import org.yaml.snakeyaml.Yaml;
import javax.swing.tree.DefaultMutableTreeNode;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class YamlToTreeNodeCreator {

    public static DefaultMutableTreeNode createTreeNodeFromYaml(String yamlFile) {
        Yaml yaml = new Yaml();
        try (InputStream in = YamlToTreeNodeCreator.class.getResourceAsStream(yamlFile)) {
            Iterable<Object> itr = yaml.loadAll(in);
            for (Object o : itr) {
                if (o instanceof Map) {
                    Map<?, ?> map = (Map) o;
                    for (Map.Entry<?, ?> entry : map.entrySet()) {
                        DefaultMutableTreeNode root = new DefaultMutableTreeNode(entry.getKey());
                        createTreeNode(entry.getValue(), root);
                        return root;
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    public static void createTreeNode(Object o, DefaultMutableTreeNode parentNode) {
        if (o instanceof Map) {
            Map<?, ?> map = (LinkedHashMap) o;
            for (Map.Entry<?, ?> entry : map.entrySet()) {
                DefaultMutableTreeNode node = new DefaultMutableTreeNode(entry.getKey());
                parentNode.add(node);
                createTreeNode(entry.getValue(), node);
            }
        } else if (o instanceof List) {
            List<?> list = (List<?>) o;
            for (Object e : list) {
                createTreeNode(e, parentNode);
            }
        } else if (o instanceof String) {
            DefaultMutableTreeNode node = new DefaultMutableTreeNode(o);
            parentNode.add(node);
        }
    }
}

Main class

public class TreeExampleMain {
    public static void main(String[] args) {
        TreeNode treeNode =
                YamlToTreeNodeCreator.createTreeNodeFromYaml("/countries.yml");
        JTree tree = new JTree(treeNode);
        tree.setCellRenderer(new CountriesTreeRenderer());
        tree.addTreeSelectionListener(createTreeSelectionListener());
        JFrame frame = createFrame();
        frame.add(new JScrollPane(tree));
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private static TreeSelectionListener createTreeSelectionListener() {
        return treeSelectionEvent -> {
            TreePath path = treeSelectionEvent.getPath();
            System.out.println("Path: " + path);
            String nodeType = null;
            Object userObject = null;
            Object[] paths = path.getPath();
            switch (paths.length) {
                case 1:
                    nodeType = "World";
                    userObject = paths[0];
                    break;
                case 2:
                    nodeType = "Continent";
                    userObject = paths[1];
                    break;
                case 3:
                    nodeType = "Country";
                    userObject = paths[2];
                    break;
            }
            System.out.printf("nodeType: %s, userObject: %s%n", nodeType, userObject);
            System.out.println("-------");
        };
    }

    private static JFrame createFrame() {
        JFrame frame = new JFrame("JTree from YAML example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(new Dimension(500, 400));
        return frame;
    }
}

YAML file

src/main/resources/countries.yml

world:
  - Africa:
      - Nigeria
      - Tanzania
      - Tunisia
      - Zambia
  - North America:
      - Canada
      - USA
      - Mexico
      - Cuba
      - Jamaica
  - Sourth America:
      - Argentina
      - Colombia
      - Ecuador
      - Chile
       -Brazil
  - Europe:
      - Norway
      - France
      - Germany
      - Italy
      - UK
  - Asia:
      - Japan
      - Singapore
      - South Korea
      - Myanmar
  - Australia:
      - Papua New Guinea
      - Australia


Tree Renderer

public class CountriesTreeRenderer extends DefaultTreeCellRenderer {

    @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);
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
        switch (node.getPath().length) {
            case 1:
                setForeground(Color.BLUE);//world
                break;
            case 2:
                setForeground(Color.MAGENTA);//continent
                break;
            case 3:
                setForeground(Color.GREEN.darker());//country
                break;
        }
        return this;
    }
}

Output

Example Project

Dependencies and Technologies Used:

  • snakeyaml 1.21: YAML 1.1 parser and emitter for Java.
  • JDK 10
  • Maven 3.5.4

Creating JTree From YAML data Select All Download
  • jtree-build-from-yaml
    • src
      • main
        • java
          • com
            • logicbig
              • example
              • uicommon
                • YamlToTreeNodeCreator.java
          • resources

    See Also