-1

Before we start, I'd like to note that I'm rather new to JTree and its relatives.

The children in my nodes show the relative path back to its parent, but I'd like for it not to.

Here is a picture of what it looks like

http://puu.sh/azCJa/8dd84029b7.png JTree

I'd like for it to be like:

testing 0
>testing 1
>>file 1

not

testing 0
>testing 0\testing 1
>>...

Here is some runnable code.

import java.awt.Color;
import java.io.File;
import java.util.Collections;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.border.LineBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeSelectionModel;

public class NGui {

    JFrame frame;
    private JTree tree;

    public NGui() {
        initialize();
    }

    private void initialize() {
        frame = new JFrame();
        frame.setResizable(false);
        frame.setBounds(100, 100, 493, 608);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setBounds(10, 11, 212, 500);
        frame.getContentPane().add(scrollPane);

        tree = new JTree(addNodes(null, new File(getWorkPath())));
        tree.setRootVisible(false);
        tree.setShowsRootHandles(true);

        tree.setBorder(new LineBorder(new Color(0, 0, 0)));
        tree.getSelectionModel().setSelectionMode(
                TreeSelectionModel.SINGLE_TREE_SELECTION);
        scrollPane.setViewportView(tree);

        tree.getSelectionModel().addTreeSelectionListener(
                new TreeSelectionListener() {
                    @Override
                    public void valueChanged(TreeSelectionEvent e) {
                        treeValueChanged(e);
                    }
                });
    }

    private String getWorkPath() {
        return System.getProperty("user.home") + "\\Program Name\\";
    }

    private void treeValueChanged(TreeSelectionEvent e) {
    }

    DefaultMutableTreeNode addNodes(DefaultMutableTreeNode top, File dir) {
        String curPath = dir.getPath();
        DefaultMutableTreeNode root = new DefaultMutableTreeNode(
                curPath.replace(getWorkPath(), ""));
        if (top != null) { // should only be null at root
            log("Adding curPath: " + root);
            top.add(root);
        }
        Vector<String> ol = new Vector<String>();
        String[] tmp = dir.list();
        for (String s : tmp) {
            log("Adding file: " + s);
            ol.addElement(s);
        }
        Collections.sort(ol, String.CASE_INSENSITIVE_ORDER);
        File file;
        Vector<String> files = new Vector<String>();
        // for dirs
        for (int i = 0; i < ol.size(); i++) {
            String filePath = ol.elementAt(i);
            String newPath;

            if (curPath.equals(".")) // if root
                newPath = filePath;
            else
                // not root
                newPath = curPath + File.separator + filePath;
            file = new File(newPath);
            log(String.format("cur: %s | file: %s | new: %s", curPath,
                    filePath, newPath));
            // if not a file then go inside folder and get files
            if (file.isDirectory())
                addNodes(root, file);
            else if (filePath.contains(".txt")) // txt files only
                files.addElement(filePath);

        }
        // for files
        for (int fnum = 0; fnum < files.size(); fnum++)
            root.add(new DefaultMutableTreeNode(files.elementAt(fnum).replace(getWorkPath(), ""), true));
        return root;
    }

    public void log(Object o) {
        System.out.println(o);
    }
}
Polycoding
  • 25
  • 8
  • Consider providing a [runnable example](https://stackoverflow.com/help/mcve) which demonstrates your problem. This will result in less confusion and better responses – MadProgrammer Aug 01 '14 at 01:57
  • I would look at `newPath = curPath + File.separator + filePath` a little more closely, very closely. Add a breakpoint at this point in your code and fire up you IDE's debugger and inspect the result of this value and see what you find... – MadProgrammer Aug 01 '14 at 02:00
  • I have looked and still don't quite see the problem. Changing anything there either causes a StackOverflow or stops listing of children in nodes. Adding a runnable example to question – Polycoding Aug 01 '14 at 02:20

1 Answers1

1

The cause of your issue is here...

if (curPath.equals(".")) // if root
    newPath = filePath;
else
    // not root
    newPath = curPath + File.separator + filePath;

Basically, what it's saying is, unless you are the root node, prefix curPath (which is dir.getPath()) to the filePath...which is why you get path/path in your tree...

The entire if statement is pointless, based on what you want to achieve and be complete replace with...

newPath = filePath;

In face, you could get rid of newPath and simple use filePath directly...

Updated

Your core design is simply not capable of doing what it seems you are trying to achieve...

Trying to maintain path information as Strings is overly complicated and error prone, it is much simpler to maintain the File reference, which provides you with all the information you need to render the file name and access the file for other purposes...the right tool for the job...

Some background, the default TreeCellRenderer used by JTree simply uses the toString method of the object in the TreeModel to renderer something to the UI. In the case of DefaultMutableTreeNode, this simply uses the toString method of the userData object you pass it, so this means, when you do curPath.replace(getWorkPath(), ""), this is what eventually gets to the screen, but isn't what you want.

Instead, you should be passing the actual File to the DefaultMutableTreeNode and using a custom TreeCellRenderer to modify the value going to the screen, for example...

File Tree

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.io.File;
import java.util.Collections;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeSelectionModel;

public class NGui {

    JFrame frame;
    private JTree tree;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }
                new NGui();
            }
        });
    }

    public NGui() {
        initialize();
    }

    private void initialize() {
        frame = new JFrame();

        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setBounds(10, 11, 212, 500);
        frame.getContentPane().add(scrollPane);

        tree = new JTree(addNodes(new File(getWorkPath())));
        tree.setRootVisible(false);
        tree.setShowsRootHandles(true);

        tree.setBorder(new LineBorder(new Color(0, 0, 0)));
        tree.getSelectionModel().setSelectionMode(
                TreeSelectionModel.SINGLE_TREE_SELECTION);
        scrollPane.setViewportView(tree);

        tree.getSelectionModel().addTreeSelectionListener(
                new TreeSelectionListener() {
                    @Override
                    public void valueChanged(TreeSelectionEvent e) {
                        treeValueChanged(e);
                    }
                });
        tree.setCellRenderer(new FileTreeCellRenderer());

        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private String getWorkPath() {
//        return System.getProperty("user.home") + "\\Program Name\\";
        return ".";
    }

    private void treeValueChanged(TreeSelectionEvent e) {
    }

    public DefaultMutableTreeNode addNodes(File dir) {
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(dir);
        for (File file : dir.listFiles()) {
            if (file.isDirectory()) {
                node.add(addNodes(file));
            } else {
                node.add(new DefaultMutableTreeNode(file));
            }
        }
        return node;
    }

    public class FileTreeCellRenderer extends DefaultTreeCellRenderer {

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

    }

}

Take a look at Customizing a Tree's Display for more details

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • curPath is the path to the folder filePath is the file/folder itself Your suggestion doesnt work, **unless** im doing it wrong. – Polycoding Aug 01 '14 at 02:37
  • But you don't need it for display purpose, the `DefaultTreeNode` only needs the `filePath` value...in fact, I would stop using `String` and use `File` instead, but that would require to provide a `TreeCellRenderer` – MadProgrammer Aug 01 '14 at 02:42
  • I need the absolute path to the file because I am previewing and modifying selected file, that's why I am doing it the way I am. – Polycoding Aug 01 '14 at 02:45
  • That seems a lot easier than i was making it. Thanks :) – Polycoding Aug 01 '14 at 18:39