探索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);
}
}
感谢所有答案。问候。
答案 0 :(得分:1)
您需要使用TreeModel
类(例如DefaultTreeModel
)作为树中节点的模型。它具有系统确定给定节点是否为叶子的方法,以及是否允许任何节点包含子节点或者是否(如在您的情况下)仅某些节点可以包含子节点。
您的程序不使用自己的模型,因此JTree
只创建自己的模型;因为它创建的模型没有办法告诉节点是否是一个叶子,除非它被展开,然后它不知道它是带有子节点的父节点,直到它被扩展并且监听器向它添加节点。