Java 实现资源管理器 JTree为什么主盘符(C D E)会出现两次, 还有显示也有点不爽 Why 
我是根据  Java 2图形设计 卷II SWING 中的一个程序改的.
原程序实现了指定(E)盘下的文件遍历
而我的目的是: 遍历本地系统中的文件结构
做了一下午, 树这里还是有问题, 主盘符(C D E)会出现两次, 还有显示也有点不爽
请高人能帮我看一下,拜托了import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;public class Test extends JFrame {
private DefaultTreeModel createTreeModel() {  // 创建根结点, 只执行一次
/* File root = new File("E:/");
FileNode rootNode = new FileNode(root); rootNode.explore();  // 第一层结构显示
*/
TreeNodeData me  = new TreeNodeData("My Computer");
me.addChileNodes();
return new DefaultTreeModel( me );
}

public Test() {
final JTree tree = new JTree(createTreeModel());  // 返回的是根结点 DefaultTreeModel
JScrollPane l_scrollPane = new JScrollPane(tree);
getContentPane().add(l_scrollPane, BorderLayout.WEST);

final JTextArea textArea = new JTextArea(10,10);
JScrollPane r_scrollPane = new JScrollPane(textArea);
getContentPane().add(r_scrollPane, BorderLayout.CENTER);

//getContentPane().add(GJApp.getStatusArea(), BorderLayout.SOUTH); tree.addTreeExpansionListener(new TreeExpansionListener(){  // 重写JTree的事件监听器
public void treeCollapsed(TreeExpansionEvent e) {
}
public void treeExpanded(TreeExpansionEvent e) {
TreePath path = e.getPath();  // 表示到某节点的一条路径   返回已被扩张 / 折叠的值的路径
FileNode node = (FileNode)path.getLastPathComponent();  // 文件路径 <- (树)路径的最后一个组件 if( ! node.isExplored()) {  // public boolean isExplored() { return explored; }  该节点从未打开时为false
DefaultTreeModel model = (DefaultTreeModel)tree.getModel();  // 返回提供数据的 TreeModel
GJApp.updateStatus("exploring ..."); UpdateStatus updateThread;
UpdateStatus us = new UpdateStatus();
us.start(); node.explore();
model.nodeStructureChanged(node);  // 当彻底改变节点的子节点和子节点的子节点... 时调用该方法,这将导致记入一个 treeStructureChanged 事件
} }
class UpdateStatus extends Thread {
public void run() {
try { Thread.currentThread().sleep(450); }
catch(InterruptedException e) { } SwingUtilities.invokeLater(new Runnable() {
public void run() {
GJApp.updateStatus(" ");
}
});
}
}
});
} public static void main(String args[]) {
GJApp.launch(new Test(),"JTree File Explorer", 300,300,450,400);
}
}
class FileNode extends DefaultMutableTreeNode {
private boolean explored = false;

public FileNode(File file)  { 
setUserObject(file); 
}
public String toString() {
File file = (File)getUserObject();
String filename = file.toString();
int index = filename.lastIndexOf(File.separator);

return (index != -1 && index != filename.length()-1) ? 
filename.substring(index+1) : 
filename;
}

public boolean getAllowsChildren() { return isDirectory(); }
public boolean isLeaf()  { return !isDirectory(); }
public File getFile() { return (File)getUserObject(); }  // 文件

public boolean isExplored() { return explored; }

public boolean isDirectory() {
File file = getFile();  // 文件名
return file.isDirectory();  // 测试当前 File 对象表示的文件是否是一个路径, 还能展开
}

public void explore() {  // 递归实现
if(!isDirectory())   // 当前文件路径所对应是系统文件是文件夹吗?  
return;

if(!isExplored()) {  // 该层第一次被打开, 展开当前结点的所有子元素
File file = getFile();  // 该节点的用户对象
File[] children = file.listFiles();

for(int i=0; i < children.length; ++i) 
add(new FileNode(children[i]));  // 子元素被实例化, 并添加到当前节点下 
// 系统是如何分辨子元素是文件夹还是文件, 因为涉及到两种图标

explored = true;
System.out.println("文件夹被第一次打开, 添加新节点时执行");
}
}
}

class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");

public static void launch(final JFrame f, String title,
  final int x, final int y, 
  final int w, int h) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void updateStatus(String s) {
status.setText(s);
}
} class TreeNodeData extends DefaultMutableTreeNode  // 
{
private File data;
private String title;

public TreeNodeData(String title)
{
super(title);
data = new File(title);
this.title = title;
}
public void addChileNodes()
{
File drivers[] = File.listRoots();
for(int i = 0;i < drivers.length;i++)
{
this.add(new TreeNodeData(drivers[i],drivers[i].getPath()));
}

}

public TreeNodeData(File file,String title)
{
super(file.getPath());
data = file;
this.title = title;

File a = new File(title);
FileNode b = new FileNode(a);
add( b );
}
}

解决方案 »

  1.   

    原程序import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.tree.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.io.File;
    import java.util.EventObject;public class Test extends JFrame {
    private DefaultTreeModel createTreeModel() {  // 创建根结点, 只执行一次
    File root = new File("E:/");
    FileNode rootNode = new FileNode(root);

    rootNode.explore();  // 第一层结构显示
    return new DefaultTreeModel(rootNode);
    }

    public Test() {
    final JTree tree = new JTree(createTreeModel());  // 返回的是根结点 DefaultTreeModel
    JScrollPane l_scrollPane = new JScrollPane(tree);
    getContentPane().add(l_scrollPane, BorderLayout.WEST);

    final JTextArea textArea = new JTextArea(10,10);
    JScrollPane r_scrollPane = new JScrollPane(textArea);
    getContentPane().add(r_scrollPane, BorderLayout.CENTER);

    //getContentPane().add(GJApp.getStatusArea(), BorderLayout.SOUTH); tree.addTreeExpansionListener(new TreeExpansionListener(){  // 重写JTree的事件监听器
    public void treeCollapsed(TreeExpansionEvent e) {
    }
    public void treeExpanded(TreeExpansionEvent e) {
    TreePath path = e.getPath();  // 表示到某节点的一条路径   返回已被扩张 / 折叠的值的路径
    FileNode node = (FileNode)path.getLastPathComponent();  // 文件路径 <- (树)路径的最后一个组件 if( ! node.isExplored()) {  // public boolean isExplored() { return explored; }  该节点从未打开时为false
    DefaultTreeModel model = (DefaultTreeModel)tree.getModel();  // 返回提供数据的 TreeModel
    GJApp.updateStatus("exploring ..."); UpdateStatus updateThread;
    UpdateStatus us = new UpdateStatus();
    us.start(); node.explore();
    model.nodeStructureChanged(node);  // 当彻底改变节点的子节点和子节点的子节点... 时调用该方法,这将导致记入一个 treeStructureChanged 事件
    } }
    class UpdateStatus extends Thread {
    public void run() {
    try { Thread.currentThread().sleep(450); }
    catch(InterruptedException e) { } SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    GJApp.updateStatus(" ");
    }
    });
    }
    }
    });
    } public static void main(String args[]) {
    GJApp.launch(new Test(),"JTree File Explorer", 300,300,450,400);
    }
    }
    class FileNode extends DefaultMutableTreeNode {
    private boolean explored = false; public FileNode(File file)  { 
    setUserObject(file); 
    }
    public String toString() {
    File file = (File)getUserObject();
    String filename = file.toString();
    int index = filename.lastIndexOf(File.separator); return (index != -1 && index != filename.length()-1) ? 
    filename.substring(index+1) : 
    filename;
    }

    public boolean getAllowsChildren() { return isDirectory(); }
    public boolean isLeaf()  { return !isDirectory(); }
    public File getFile() { return (File)getUserObject(); }  // 文件 public boolean isExplored() { return explored; } public boolean isDirectory() {
    File file = getFile();  // 文件名
    return file.isDirectory();  // 测试当前 File 对象表示的文件是否是一个路径, 还能展开
    } public void explore() {  // 递归实现
    if(!isDirectory())   // 当前文件路径所对应是系统文件是文件夹吗?  
    return;

    if(!isExplored()) {  // 该层第一次被打开, 展开当前结点的所有子元素
    File file = getFile();  // 该节点的用户对象
    File[] children = file.listFiles(); for(int i=0; i < children.length; ++i) 
    add(new FileNode(children[i]));  // 子元素被实例化, 并添加到当前节点下 
    // 系统是如何分辨子元素是文件夹还是文件, 因为涉及到两种图标 explored = true;
    System.out.println("文件夹被第一次打开, 添加新节点时执行");
    }
    }
    }
    class GJApp extends WindowAdapter {
    static private JPanel statusArea = new JPanel();
    static private JLabel status = new JLabel(" "); public static void launch(final JFrame f, String title,
      final int x, final int y, 
      final int w, int h) {
    f.setTitle(title);
    f.setBounds(x,y,w,h);
    f.setVisible(true); statusArea.setBorder(BorderFactory.createEtchedBorder());
    statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
    statusArea.add(status);
    status.setHorizontalAlignment(JLabel.LEFT); f.setDefaultCloseOperation(
    WindowConstants.DISPOSE_ON_CLOSE); f.addWindowListener(new WindowAdapter() {
    public void windowClosed(WindowEvent e) {
    System.exit(0);
    }
    });
    }
    static public JPanel getStatusArea() {
    return statusArea;
    }
    static public void updateStatus(String s) {
    status.setText(s);
    }
    }
      

  2.   

    class TreeNodeData
    extends DefaultMutableTreeNode //
    {
    private File data; private String title; public TreeNodeData(String title)
    {
    super(title);
    data = new File(title);
    this.title = title;
    } public void addChileNodes()
    {
    File drivers[] = File.listRoots();
    for (int i = 0; i < drivers.length; i++) {
    this.add(new FileNode(drivers[i]));   //这儿改了
    } } public TreeNodeData(File file, String title)
    {
    super(file.getPath());
    data = file;
    this.title = title; File a = new File(title);
    FileNode b = new FileNode(a);
    add(b);
    }
    }
      

  3.   

    http://61.186.252.131/Expert/topic/1961/1961041.xml?temp=.59956
      

  4.   

    带复选框的资源管理器的树目录楼主可以参考一下
    http://sunfruit.blogchina.com/985893.html