📄 folderexplorer.java
字号:
/*程序文件名称:FolderExplorer.java
*功能:显示文件目录树
*/
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.io.*;
import java.util.*;
public class FolderExplorer extends JFrame
{
JScrollPane jScrollPane1=new JScrollPane();
JTree tree;
DefaultTreeModel treeModel;
JLabel lbStatus=new JLabel();
//构造方法,对界面进行初始化
public FolderExplorer()
{
try{
//调用jbInit()方法完成界面初始化
jbInit();
}catch(Exception e){ e.printStackTrace(); }
}
//main()方法,程序运行的入口
public static void main(String[]args)
{
FolderExplorer FolderExplorer1=new FolderExplorer();
}
//jbInit()方法完成对界面进行初始化的任务
public void jbInit()throws Exception
{
initTree();
this.setTitle("Java Folder Explorer");
this.setSize(new Dimension(400,300));
this.getContentPane().add(jScrollPane1,BorderLayout.CENTER);
this.getContentPane().add(lbStatus,BorderLayout.SOUTH);
jScrollPane1.getViewport().add(tree,null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
//初始化树状结构
void initTree()
{
//定义根结点
DefaultMutableTreeNode top=new DefaultMutableTreeNode("My Computer");
//定义子结点
DefaultMutableTreeNode node;
//定义文件列表
File[]roots=File.listRoots();
//使用循环结构将读取的磁盘盘符当作树的一级结点
for(int i=0;i<roots.length;i++)
{
node=new DefaultMutableTreeNode(new FileNode(roots[i]));
top.add(node); //top为根结点
//暂时在各个一级结点下增加子结点Retrieving data
node.add(new DefaultMutableTreeNode(new String("Retrieving data")));
}
treeModel=new DefaultTreeModel(top);
tree=new JTree(treeModel);
//使JTREE具有类似Windows文件管理器的直角连接线
tree.putClientProperty("JTree.lineStyle","Angled");
//添加JTREE的展开事件的侦听
tree.addTreeExpansionListener(new MyExpansionListener());
//添加JTREE的选择事件的侦听
tree.addTreeSelectionListener(new MySelectionListener());
//使树形结构一次只能选择一个结点
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
tree.setShowsRootHandles(true);
tree.setEditable(false);
}
//该方法为获取最新被选择的结点,并返回
DefaultMutableTreeNode getTreeNode(TreePath path)
{
return(DefaultMutableTreeNode)(path.getLastPathComponent());
}
//返回结点,该结点类型为FileNode
FileNode getFileNode(DefaultMutableTreeNode node)
{
if(node==null)
{
return null;
}
//获取与node结点相关的信息
Object obj=node.getUserObject();
//用instanceof关键字判断obj对象是否是filenode的实例
if(obj instanceof FileNode)
{
return(FileNode)obj;
}
else
{
return null;
}
}
//JTREE的展开事件的处理
class MyExpansionListener implements TreeExpansionListener
{
public void treeExpanded(TreeExpansionEvent e)
{
final DefaultMutableTreeNode node=getTreeNode(e.getPath());
//获取最新被选择的结点,并将其赋值给node
final FileNode fileNode=getFileNode(node);
//应用线程,将结点转化为FileNode类型
Thread runner=new Thread()
{
public void run()
{
//如果是子结点
if(fileNode !=null&&fileNode.expand(node))
{
Runnable runnable=new Runnable()
{
public void run()
{ treeModel.reload(node); }
};
//将Runnable对象传送给它,并且在事件线程中执行指定的Runnable
SwingUtilities.invokeLater(runnable);
}
} //run()end
}; //Thread()end
//启动线程
runner.start();
}
public void treeCollapsed(TreeExpansionEvent e){
}
} //MyExpansionListener类end
//处理JTREE的选择侦听事件
class MySelectionListener implements TreeSelectionListener
{
public void valueChanged(TreeSelectionEvent e)
{
DefaultMutableTreeNode node=getTreeNode(e.getPath());
FileNode fileNode=getFileNode(node);
if(fileNode!=null)
{
//在底下的标签里显示该结点的路径
lbStatus.setText(fileNode.getFile().getAbsolutePath());
}
else{ lbStatus.setText(""); }
}
} //MySelectionListenner类 end
//FileNode类用于获取系统中的文件目录结点
class FileNode
{
File file;
//构造方法
public FileNode(File file)
{
this.file=file;
}
public File getFile()
{
return file;
}
//若为文件则返回文件名,不是则返回结点路径
public String toString()
{
return file.getName().length()>0?file.getName():file.getPath();
}
//判断各结点是否有子结点
public boolean expand(DefaultMutableTreeNode parent)
{
DefaultMutableTreeNode child=(DefaultMutableTreeNode)parent.getFirstChild();
if(child==null)
{
return false;
}
//whether child is the String flag?
Object obj=child.getUserObject();
if(!(obj instanceof String))
{
return false;
}
//删除标记的子结点
parent.removeAllChildren();
//listFiles()方法得到表示子文件列表并将其赋值给File数组
File[]files=listFiles();
if(files==null)
{
return true;
}
//定义向量Vector存放文件结点
Vector v=new Vector();
//用外循环将文件目录加入向量
for(int i=0;i<files.length;i++)
{
File f=files[i];
//isDirectory()方法判断这个获取的实例是否是文件夹
if(!(f.isDirectory()))
{
//如果不是则继续查找
continue;
}
FileNode newNode=new FileNode(f);
boolean isAdded=false;
//用内循环列出文件结点
for(int j=0;j<v.size();j++)
{
FileNode node=(FileNode)v.elementAt(j);
if(newNode.compareTo(node)<0)
{
//判断newNode在不在node中
//把组件加到索引j处,此后的内容向后移动1个单位
v.insertElementAt(newNode,j);
isAdded=true;
break;
}
} //内循环列文件结点结束
if(!isAdded)
{
//把新结点加到向量尾部,同时大小加1
v.addElement(newNode);
}
} //外循环结束
//用循环处理子结点
for(int i=0;i<v.size();i++)
{
//循环给父结点加入子结点
FileNode fileNode=(FileNode)v.elementAt(i);
DefaultMutableTreeNode node=new DefaultMutableTreeNode(fileNode);
parent.add(node);
//若还有子目录则将子目录作为子结点加到node
if(fileNode.hasSubDirs())
{
node.add(new DefaultMutableTreeNode(new String("Retriveving data")));
}
} //用循环处理子结点,结束
return true;
}//判断是否有子结点expand()方法结束
public boolean hasSubDirs()
{
//listFiles()方法得到子文件列表并将其赋值给File数组
File[]files=listFiles();
if(files==null)
{
return false;
}
for(int i=0;i<files.length;i++)
{
if(files[i].isDirectory())
{
return true;
}
}
return false;
}
//判断文件目录是否相同,并返回一个int类型的数
public int compareTo(FileNode toCompare)
{
return file.getName().compareToIgnoreCase(toCompare.file.getName());
}
//得到子文件列表
File[]listFiles()
{
//判断是否为文件夹
if(!file.isDirectory())
{ return null; }
try{
//返回子文件列表
return file.listFiles();
}
catch(Exception ex)
{
ex.printStackTrace();
return null;
}
} //listFiles()方法 end
} //FileNode类 end
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -