Search code examples
javaswingjtree

Populate JTree from String array Structured as Paths


I need help in my Java project. How do I populate my JTree dynamically from arrays of String patterned as paths?. Like, String

paths[][]={{"Animals", "Birds","Non_flying" ,"Chicken"},
{"Animals","Birds","Non_flying","Ostrich"}, 
{"Animals","Birds","Flying","Eagle"},
{"Animals","Birds","Flying","Crow"},
{"Animals","Reptiles","Lizard"},
{"Plants"," Fruit Bearing","Fruits","Mango"},
{"Plants"," Fruit Bearing","Vegetable","Eggplant"},
{"Plants"," Non-fruit Bearing","Sunflower"}};

Like this I tried the code below but it does not merge similar nodes. It must be the conditions inside the treeify() method:

import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;

public class TreeTest extends javax.swing.JFrame{
    static JTree tree; 
    public static void setTree(){
        String paths[][]={{"Animals", "Birds","Non_flying" ,"Chicken"},
                         {"Animals","Birds","Non_flying","Ostrich"},    
                         {"Animals","Birds","Flying","Eagle"},
                         {"Animals","Birds","Flying","Crow"},
                         {"Animals","Reptiles","Lizard"},
                         {"Plants"," Fruit Bearing","Fruits","Mango"},
                         {"Plants"," Fruit Bearing","Vegetable","Eggplant"}, 
                         {"Plants"," Non-fruit Bearing","Sunflower"}};
        tree = new JTree(treeify(paths)); 
    }

    public static <T> DefaultMutableTreeNode treeify(String[][] paths) {
        DefaultMutableTreeNode root = null;
        DefaultMutableTreeNode subRoot = null;
        for ( String[] parent : paths)
        for ( String value : parent){
            if (root == null) {
                root = new DefaultMutableTreeNode(value);
            } else if (subRoot == null){
                subRoot = new DefaultMutableTreeNode(value);
                root.add(subRoot);
            } else {
                DefaultMutableTreeNode child = new DefaultMutableTreeNode(value);
                subRoot.add(child);
                subRoot = child;
            }
        }
        return root; 
    }

    public static void main(String[] args) {
        TreeTest test = new TreeTest();
        setTree();
        test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        test.add(new JScrollPane(tree));
        test.setSize(500,400);
        test.setLocationRelativeTo(null);
        test.setVisible(true); 
    }
}

Solution

  • Here's a version of treeify() that implements the strategy I was outlining in my comment. It's not the most elegant thing ever, but it gets the job done:

    public static DefaultMutableTreeNode treeify(String[][] paths) {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode();
        for ( String[] path : paths) {
            DefaultMutableTreeNode curr = root;
            for ( String value : path){
                DefaultMutableTreeNode next = null;
                Enumeration ce = curr.children();
                while (ce.hasMoreElements()){
                    DefaultMutableTreeNode kid = 
                        (DefaultMutableTreeNode) ce.nextElement();
                    if (((String)kid.getUserObject()).equals(value)){
                        next = kid;
                        break;
                    }
                }
                if (next == null){
                    next = new DefaultMutableTreeNode(value);
                    curr.add(next);
                }
                curr = next;
            }
        }
        return root; 
    }