Java JTree from directory (shows full path instead of just the name of the file)

浪尽此生 提交于 2021-01-28 18:13:59

问题


I wanted to make a tree from an existing directory, so that it shows all of the subfolders and files inside. I did it with this code:

File file = new File(path); TreeModel model = new FileTreeModel(file); JTree tree = new JTree(model);

But now it shows the full path instead of just the folder/file name. If you don't know what I mean, this might help: Please help... I wanted to find the solution online but I didn't know how to describe the problem. :/


回答1:


import java.io.File;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.WindowConstants;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

class FileTreeModel implements TreeModel {
    private final ArrayList<TreeModelListener>  mListeners  = new ArrayList<>();
    private final MyFile                        mFile;

    public FileTreeModel(final MyFile pFile) {
        mFile = pFile;
    }
    @Override public Object getRoot() {
        return mFile;
    }
    @Override public Object getChild(final Object pParent, final int pIndex) {
        return ((MyFile) pParent).listFiles()[pIndex];
    }
    @Override public int getChildCount(final Object pParent) {
        return ((MyFile) pParent).listFiles().length;
    }
    @Override public boolean isLeaf(final Object pNode) {
        return !((MyFile) pNode).isDirectory();
    }
    @Override public void valueForPathChanged(final TreePath pPath, final Object pNewValue) {
        final MyFile oldTmp = (MyFile) pPath.getLastPathComponent();
        final File oldFile = oldTmp.getFile();
        final String newName = (String) pNewValue;
        final File newFile = new File(oldFile.getParentFile(), newName);
        oldFile.renameTo(newFile);
        System.out.println("Renamed '" + oldFile + "' to '" + newFile + "'.");
        reload();
    }
    @Override public int getIndexOfChild(final Object pParent, final Object pChild) {
        final MyFile[] files = ((MyFile) pParent).listFiles();
        for (int i = 0; i < files.length; i++) {
            if (files[i] == pChild) return i;
        }
        return -1;
    }
    @Override public void addTreeModelListener(final TreeModelListener pL) {
        mListeners.add(pL);
    }
    @Override public void removeTreeModelListener(final TreeModelListener pL) {
        mListeners.remove(pL);
    }

    /**
     *  stolen from http://developer.classpath.org/doc/javax/swing/tree/DefaultTreeModel-source.html
     *
      * <p>
      * Invoke this method if you've modified the TreeNodes upon which this model
      * depends. The model will notify all of its listeners that the model has
      * changed. It will fire the events, necessary to update the layout caches and
      * repaint the tree. The tree will <i>not</i> be properly refreshed if you
      * call the JTree.repaint instead.
      * </p>
      * <p>
      * This method will refresh the information about whole tree from the root. If
      * only part of the tree should be refreshed, it is more effective to call
      * {@link #reload(TreeNode)}.
      * </p>
      */
    public void reload() {
        // Need to duplicate the code because the root can formally be
        // no an instance of the TreeNode.
        final int n = getChildCount(getRoot());
        final int[] childIdx = new int[n];
        final Object[] children = new Object[n];

        for (int i = 0; i < n; i++) {
            childIdx[i] = i;
            children[i] = getChild(getRoot(), i);
        }

        fireTreeStructureChanged(this, new Object[] { getRoot() }, childIdx, children);
    }

    /**
     * stolen from http://developer.classpath.org/doc/javax/swing/tree/DefaultTreeModel-source.html
     *
     * fireTreeStructureChanged
     *
     * @param source the node where the model has changed
     * @param path the path to the root node
     * @param childIndices the indices of the affected elements
     * @param children the affected elements
     */
    protected void fireTreeStructureChanged(final Object source, final Object[] path, final int[] childIndices, final Object[] children) {
        final TreeModelEvent event = new TreeModelEvent(source, path, childIndices, children);
        for (final TreeModelListener l : mListeners) {
            l.treeStructureChanged(event);
        }
    }
}

class MyFile {
    private final File mFile;

    public MyFile(final File pFile) {
        mFile = pFile;
    }

    public boolean isDirectory() {
        return mFile.isDirectory();
    }

    public MyFile[] listFiles() {
        final File[] files = mFile.listFiles();
        if (files == null) return null;
        if (files.length < 1) return new MyFile[0];

        final MyFile[] ret = new MyFile[files.length];
        for (int i = 0; i < ret.length; i++) {
            final File f = files[i];
            ret[i] = new MyFile(f);
        }
        return ret;
    }

    public File getFile() {
        return mFile;
    }

    @Override public String toString() {
        return mFile.getName();
    }
}

public class FileWrapperDeluxe {
    public static void main(final String[] args) {
        final JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        f.setBounds(100, 100, 400, 400);

        final File file = new File("E:\\");
        final MyFile mf = new MyFile(file);
        final TreeModel model = new FileTreeModel(mf);

        final JTree tree = new JTree(model);
        tree.setEditable(true);

        f.add(new JScrollPane(tree));
        f.setVisible(true);
    }
}


来源:https://stackoverflow.com/questions/36804035/java-jtree-from-directory-shows-full-path-instead-of-just-the-name-of-the-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!