【问题标题】:Java JTree from directory (shows full path instead of just the name of the file)目录中的 Java JTree(显示完整路径,而不仅仅是文件名)
【发布时间】:2016-08-16 16:29:46
【问题描述】:

我想从现有目录中创建一棵树,以便显示其中的所有子文件夹和文件。我用这段代码做到了:

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

但现在它显示的是完整路径,而不仅仅是文件夹/文件名。如果您不明白我的意思,这可能会有所帮助: 请帮助...我想在网上找到解决方案,但我不知道如何描述问题。 :/

【问题讨论】:

  • 不要直接使用File,而是编写自己的封装File的类,然后实现它的toString()方法。
  • @JayC667 感谢您的建议,但我不太清楚该怎么做... :/ 如果您有时间,请把该课程的代码发给我好吗? :)

标签: java path tree directory


【解决方案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);
    }
}

【讨论】:

  • 更改我的示例,添加tree.setEditable(true);,然后重命名,然后你会看到该怎么做;-)
  • 您的TreeModel 的方法valueForPathChanged 被调用。检查它的参数,它们会为您提供重命名所需的所有信息。
  • 你真的想改变实际的文件名,例如重命名真实的文件和目录,还是只是想在你的应用程序中显示一个虚拟文件系统?
  • 好的,检查一下:我已经稍微改变了我的解决方案。添加了reload()fireTreeStructureChanged() 方法,并更改了valueForPathChanged() 方法。像魅力一样工作,即使我没有包括任何支票。现在由你决定。哦,顺便说一句,您还可以使用“DefaultTreeModel”,使更新和大多数其他内容变得更加容易。在谷歌上查看解决方案 ;-)
猜你喜欢
  • 2012-01-21
  • 2022-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-01
  • 2023-03-25
  • 1970-01-01
相关资源
最近更新 更多