JTree:为什么我的目录看起来不像目录?

时间:2016-01-30 13:03:42

标签: java nodes jtree expand

探索JTree组件,我写了一个小类,它将列出我硬盘的目录和文件。为了避免需要很长时间并且浪费时间和资源的“全面扫描”,我决定只探索“活动节点”的1个子级别。 “主动节点”是指单击目录或节点展开。

对于单击的目录,它运行正常:我可以浏览我的目录和子目录,代码工作“子级别的子级别”,单击的目录显示为目录。

但如果我展开一个节点,那就失败了!探索此节点的子节点的方法运行;它找到所有的孩子并可以通过“System.out.println(...)”列出它们,但我的目录仍然像文件一样,即使他们有孩子。要使目录看起来像目录,我必须单击它(=使用“第一种方法”)。

这是我的代码。有人能解释我失败的原因吗?

import java.awt.BorderLayout;
import java.io.File;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

public class Explorer2 extends JPanel {
private JTree tree;
private DefaultMutableTreeNode root= new DefaultMutableTreeNode();
int countSubLevel=0;
int limit=1;

Explorer2() {
    DefaultMutableTreeNode driveNode=null;
    for (File file:File.listRoots()) {
        driveNode = new DefaultMutableTreeNode(file.getAbsolutePath());
        //testLeaf(driveNode);          
        exploreDirectory(file, driveNode);
        root.add(driveNode);
    }

    displayTree();
}

Explorer2(String rootDirectory) {
    File file = new File(rootDirectory);
    DefaultMutableTreeNode directoryNode = new DefaultMutableTreeNode(file.getAbsolutePath());
    exploreDirectory(file, directoryNode);
    root.add(directoryNode);
    displayTree();
}

public void exploreDirectory (File dir, DefaultMutableTreeNode dirNode) {
    if (dir.isDirectory()) {
        //System.out.println(dir+" (parent) is a directory. Its level is : "+dirNode.getLevel());
        try {
            for (File file:dir.listFiles()) {
                DefaultMutableTreeNode fileNode = new DefaultMutableTreeNode(file.getAbsolutePath()); 

                dirNode.add(fileNode);
                //System.out.println(dirNode+" - "+file+" - Level = "+fileNode.getLevel());
                /*
                if (fileNode.getLevel()<limit) {
                    System.out.println(file+" (child) have a level : "+fileNode.getLevel());
                    exploreDirectory(file, fileNode);
                } else {
                    //System.out.println("Not in the loop : "+fileNode.getLevel());
                }
                */

            }

        } catch (NullPointerException e) {
            System.err.println(dir+" generates a NullPointerException");
        }           

    } else {
        System.out.println(dir+" is a file. Its level is : "+dirNode.getLevel());
    }
    countSubLevel+=1;
}

public void displayTree () {
    DefaultTreeModel treeModel = new DefaultTreeModel(root);
    tree = new JTree(treeModel);
    //tree = new JTree(root);
    tree.setRootVisible(true);
    tree.addTreeSelectionListener(new MyTreeSelectionListener());
    tree.addTreeExpansionListener(new MyTreeExpansionListener());


    this.setLayout(new BorderLayout());
    this.add(new JScrollPane(tree), BorderLayout.CENTER);
}

public void testLeaf(DefaultMutableTreeNode dir) {
    if (dir.isLeaf()) {
        System.out.println("Rien en dessous de "+dir);
    } else {
        System.out.println("Creuse !");
    }
}

class MyTreeSelectionListener implements TreeSelectionListener {
    @Override
    public void valueChanged(TreeSelectionEvent arg0) {
        if (tree.getLastSelectedPathComponent() != null) {
            File dir = new File(tree.getLastSelectedPathComponent().toString());
            DefaultMutableTreeNode dirNode = (DefaultMutableTreeNode) arg0.getPath().getLastPathComponent();
            DefaultMutableTreeNode fileNode=null;
            //System.out.println(dirNode.getChildCount());
            if (dirNode.getChildCount()==0) {
                System.out.println("The directory is : "+dir+" - Node : "+dirNode);
                exploreDirectory(dir, dirNode);
            }
        }

    }

}

class MyTreeExpansionListener implements TreeExpansionListener {

    @Override
    public void treeCollapsed(TreeExpansionEvent arg0) {
        System.out.println("Collapsed : "+arg0.getPath().getLastPathComponent());
    }

    @Override
    public void treeExpanded(TreeExpansionEvent arg0) {
        DefaultMutableTreeNode dir = (DefaultMutableTreeNode) arg0.getPath().getLastPathComponent();
        DefaultMutableTreeNode fileNode=null;
        System.out.println("Expanded directory is : "+dir+" - Number of child : "+dir.getChildCount());         
        for (int i=0 ; i<dir.getChildCount() ; i++) {

            File file = new File(dir.getChildAt(i).toString());
            fileNode = new DefaultMutableTreeNode(file.getAbsolutePath());
            exploreDirectory(file, fileNode);
            System.out.println("*"+i+" - directory is : "+dir+" - Files are : "+file+" - Number of children : "+fileNode.getChildCount());
        }           
    }       
}

public static void main(String[] args) {
    JFrame window = new JFrame ();
    window.setSize(500, 600);
    window.setTitle("Explorateur");
    window.setLocationRelativeTo(null);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setLayout(new BorderLayout());
    String str = System.getProperty("user.home");
    //Explorer2 explorer = new Explorer2(str);
    Explorer2 explorer = new Explorer2();

    window.getContentPane().add(explorer);
    window.setVisible(true);

}

}

感谢所有答案。问候。

1 个答案:

答案 0 :(得分:1)

您需要使用TreeModel类(例如DefaultTreeModel)作为树中节点的模型。它具有系统确定给定节点是否为叶子的方法,以及是否允许任何节点包含子节点或者是否(如在您的情况下)仅某些节点可以包含子节点。

您的程序不使用自己的模型,因此JTree只创建自己的模型;因为它创建的模型没有办法告诉节点是否是一个叶子,除非它被展开,然后它不知道它是带有子节点的父节点,直到它被扩展并且监听器向它添加节点。