Search code examples
javaswingjtree

JTree duplicates folder when showing


I have a custom Jtree which shows structure of a given folder. My problem is that somehow it duplicates folder.

For example given folder is C:\Example

In the example Folder there are 3 folder called A, B ,C

The JTree Supposed to view it like this:

C:\Example

->A
    some1.txt
->B
->C

but it duplicates folder so it shows:

C:\Example

 ->A
   ->A
    some1.txt
->B
  ->B
->C
  ->C

I use custom renderer to show only Name not the full path in jtree, here it is:

    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
        System.out.println(value); 
        super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
        if (value instanceof DefaultMutableTreeNode) {
            value = ((DefaultMutableTreeNode)value).getUserObject();
            if (value instanceof File) {
                File file = (File) value;
                if (file.isFile()) {
                    setText(file.getName());
                } else {
                    setText(file.getName());
                }
            }
        }
        return this;
    }

And here is where i populate the Jtree with data:

/**
 * Add nodes from under "dir" into curTop. Highly recursive.
 */
DefaultMutableTreeNode addNodes(DefaultMutableTreeNode curTop, File dir) {

    DefaultMutableTreeNode curDir = new DefaultMutableTreeNode(dir);
    if (curTop != null) { // should only be null at root
        curTop.add(curDir);
    }
    File[] tmp = dir.listFiles();
    Vector<File> ol = new Vector<File>();

    ol.addAll(Arrays.asList(tmp));
    Collections.sort(ol, new Comparator<File>() {
        @Override
        public int compare(File o1, File o2) {

            int result = o1.getName().compareTo(o2.getName());

            if (o1.isDirectory() && o2.isFile()) {
                result = -1;
            } else if (o2.isDirectory() && o1.isFile()) {
                result = 1;
            }

            return result;
        }
    });
    // Pass two: for files.
    for (int fnum = 0; fnum < ol.size(); fnum++) {
        File file = ol.elementAt(fnum);
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(file);
        if (file.isDirectory()) {
            addNodes(node, file);
        }
       curDir.add(node);
    }
    return curDir;
}

and here is where i use these in my code:

        dir = new File(System.getProperty("user.dir")+"\\Example");
    tree = new JTree(addNodes(null, dir));
    tree.setCellRenderer(new MyTreeCellRenderer());

Solution

  • You have problems with your recursion in addNodes(..) method, change it like next:

    DefaultMutableTreeNode addNodes(DefaultMutableTreeNode curTop, File dir) {
    
            File[] tmp = dir.listFiles();
            Vector<File> ol = new Vector<File>();
            ol.addAll(Arrays.asList(tmp));
            Collections.sort(ol, new Comparator<File>() {
                @Override
                public int compare(File o1, File o2) {
    
                    int result = o1.getName().compareTo(o2.getName());
    
                    if (o1.isDirectory() && o2.isFile()) {
                        result = -1;
                    } else if (o2.isDirectory() && o1.isFile()) {
                        result = 1;
                    }
    
                    return result;
                }
            });
            // Pass two: for files.
            for (int fnum = 0; fnum < ol.size(); fnum++) {
                File file = ol.elementAt(fnum);
                DefaultMutableTreeNode node = new DefaultMutableTreeNode(file);
                if (file.isDirectory()) {
                    addNodes(node, file);
                }
                curTop.add(node);
            }
            return curTop;
        }
    

    Also you need't call it with null parameter, call like next:

        JTree tree = new JTree(addNodes(new DefaultMutableTreeNode(dir), dir));