javaswingdynamicjtreedefaulttreemodel

Dynamically populating the tree model from a text file in JTree


The problem I am facing is with the tree model of the JTree.

I have defined the root node as:

    javax.swing.tree.DefaultMutableTreeNode rootNode = new javax.swing.tree.DefaultMutableTreeNode(projectName);

When the application first starts, I want the treeModel to be created and loaded. For this, I am using a file meta.txt, which has information like the following:

    1QuotesPrice.Job
    2QuotesPrice.Df
    1Quotes.Job
    2Quotes.Wf
    3Quotes.Df
    2Falkeblang.Wf
    3Falkeblang.Df

The first column is the level, and the second is the node of the tree. Now based on this information, I want to create the tree model, but am facing a roadblock here.

I am unsure of the logic to apply to add the above nodes to the root node. Every thing I have tried seems to have flaws. The problem here is the no of levels are not fixed, so I cant simply use a if-else construct. I am using the following code:

        String treeMeta=this.projectsDir+"\\"+projectName+"\\"+"meta.txt";
        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(projectName);
        File f1=new File(treeMeta);
        inputStream =  new Scanner(f1);
        while(inputStream.hasNext()){

         String val=inputStream.next();
         System.out.println("!@#$%"+val+"!@#$%");
         treeNodePrev=treeNode;
         prevLevel=level;
         level=val.substring(0,1);
         nodeVal=val.substring(1);
           if(level.equals("1")){
              prevNode=projectName;
              treeNode = new DefaultMutableTreeNode(nodeVal);
              System.out.println("added to root node");
              rootNode.add(treeNode);
              //System.out.println("added to root node");
           }else if(Integer.parseInt(level)>Integer.parseInt(prevLevel)){
               prevNode=nodeVal;
               treeNode = new DefaultMutableTreeNode(nodeVal);
               treeNodePrev.add(treeNode);
           }else if(Integer.parseInt(level)==Integer.parseInt(prevLevel)){
               prevNode=nodeVal;
               treeNode = new DefaultMutableTreeNode(nodeVal);
               prevParentTreeNode=(DefaultMutableTreeNode)treeNodePrev.getParent();
               //System.out.println(prevParentTreeNode.getParent().toString());
               prevParentTreeNode.add(treeNode);
           }
        }
         jProjectTree.setModel(new javax.swing.tree.DefaultTreeModel(rootNode));
         jScrollPane2.setViewportView(jProjectTree);

This seems to be working fine, but could anyone please tell me if this is the correct approach?


Solution

  • This might be a bit cleaner. Just adapt the function for calculating the level ...

    public static final DefaultMutableTreeNode getTreeNode(File file) throws IOException  {
    
        DefaultMutableTreeNode rootNode = null;
        Map<Integer, DefaultMutableTreeNode> levelNodes = new HashMap<Integer, DefaultMutableTreeNode>();
        BufferedReader reader = new BufferedReader(new FileReader(file));
        String line;
    
        while( (line = reader.readLine()) != null ) {
    
            int level = getLevel(line);
            String nodeName = getNodeName(line, level);
            DefaultMutableTreeNode node = new DefaultMutableTreeNode(nodeName);               
            levelNodes.put(level, node);
            DefaultMutableTreeNode parent = levelNodes.get(level - 1);
    
            if( parent != null ) {
                parent.add(node);
            }
            else {
                rootNode = node;
            }
        }    
        reader.close();
        return rootNode;
    }
    
    private static final int getLevel(String line) {
    
        int level = 0;
        for ( int i = 0; i < line.length(); i++ ) {
            char c = line.charAt(i);
            if( c == '\t') {
                level++;
            }
            else {
                break;
            }
        }
        return level;
    }
    
    private static final String getNodeName(String line, int level) {
        return line.substring(level);
    }