代码之家  ›  专栏  ›  技术社区  ›  user257111

在爪哇中高效地生成“Explorer树”(不使用递归)

  •  4
  • user257111  · 技术社区  · 14 年前

    我有一个问题,它可能是语言不可知的,但对于这个特定的实现,我使用Java。使用如下函数列出目录中的文件夹是可能的,而且相对简单:

    private DefaultMutableTreeNode GenerateFSTree(File f)
    {
        int i = 0;
        File[] Children = f.listFiles();
    
        DefaultMutableTreeNode x = new DefaultMutableTreeNode(f.getName());
    
        if ( Children != null )
        {
            for ( i = 0; i < Children.length; i++ )
            {
                File f_cur = Children[i];
                if (
                f_cur.isDirectory() && 
                ( this.DisplayHidden || !f_cur.isHidden() ) 
                )
                {   
                    x.add(GenerateFSTree(f_cur));
                }
            }
        }
    
        return x;
    }
    

    如您所见,这大量使用递归来评估文件系统,最终得到的是一个 DefaultMutableTreeNode 项目。

    现在我的问题是——有更快的方法吗?一定有,因为这很慢。尝试在上执行此操作 / 这需要永远。但是,如果我使用N鹦鹉螺或内置的Java文件选择对话框,树会立即呈现。

    所以我的问题是-我怎样才能加快速度?

    谢谢

    2 回复  |  直到 14 年前
        1
  •  2
  •   Marc-Christian Schulze    14 年前

    看看这个例子 http://www.java2s.com/Code/Java/Swing-JFC/FileTree.htm
    this treemodel 将为jtree提供文件系统结构。只有在扩展节点时才能访问文件系统…最初是针对根节点。;)

    class FileTreeModel implements TreeModel {
        protected File root;
        public FileTreeModel(File root) { this.root = root; }
    
        public Object getRoot() { return root; }
    
        public boolean isLeaf(Object node) {  return ((File)node).isFile(); }
    
        public int getChildCount(Object parent) {
            String[] children = ((File)parent).list();
            if (children == null) return 0;
        return children.length;
        }
    
        public Object getChild(Object parent, int index) {
            String[] children = ((File)parent).list();
            if ((children == null) || (index >= children.length)) return null;
        return new File((File) parent, children[index]);
        }
    
        public int getIndexOfChild(Object parent, Object child) {
            String[] children = ((File)parent).list();
            if (children == null) return -1;
                String childname = ((File)child).getName();
                for(int i = 0; i < children.length; i++) {
                    if (childname.equals(children[i])) return i;
                }
                return -1;
        }
    
        public void valueForPathChanged(TreePath path, Object newvalue) {}
    
        public void addTreeModelListener(TreeModelListener l) {}
        public void removeTreeModelListener(TreeModelListener l) {}
    
    
    }
    

    使用

    Jtree tree = new JTree(new FileTreeModel(new File("/")));
    

    此模型将阻止您使用defaultTreeNodes填充内存,并最小化对底层文件系统的访问。

        2
  •  4
  •   Russ Hayward    14 年前

    通常的方法是,一开始只读取一个目录。该顶级目录下的任何目录都不会立即读取。相反,将在创建的目录树节点下插入一个虚拟节点。当用户展开目录节点时,程序将读取相关目录,然后用反映目录内容的节点替换虚拟节点。