JTree实现电脑资源管理器
0.前言
最近老师布置了一项用Java写资源管理器的任务,一开始以为简单,但是实际操作起来,却发现网上的资源用起来相对生疏。在使用中,我也遇到了许多问题,虽然不能像其他博主一样,写的非常齐全,但我还是分享一下我写的代码。

1.准备知识
- JTree是树形结构,是我们做资源管理器的必要组件。其构造函数的参数可以是节点,或者树模型。
- JTree只有放在JScrollPane里,才可以很好的显示(因为有时候树很大,要拉很长才能看到),当然不放也可以。
- JTree是通过增加节点,来实现多层目录的。
- 一般使用DefaultMutableTreeNode来实现节点,可以通过add()函数,添加孩子节点。
- 还有些琐碎的知识点,会在第三部分一一讲述。
2.思路
一开始的思路是用DFS深搜,但是实现后发现,相当的慢。
所以,我就想先写一个“我的电脑”节点,然后往下加磁盘分区,然后当我点击一个节点的时候(用事件监听,这里用到TreeSelectionListener),再往下展开(添加节点)
3.分段代码
1.获取系统的磁盘目录
//获取磁盘目录
File roots[] = File.listRoots();
//添加至父节点
for(int i=0; i<roots.length; i++) {
father_node.add(new DefaultMutableTreeNode(roots[i]));
}
2.设置一颗完好的树,并加入面板
&&强调&&一定要先把Tree设置好之后,再添加至JScrollPane上,否则可能会出现无显示的情况&&
//设置树的模式,也可以不设置
DefaultMutableTreeNode top_node= new DefaultMutableTreeNode("我的电脑");
DefaultTreeModel treeModel = new DefaultTreeModel(top);
//设置树
JTree tree = new JTree(treeModel); //可以直接用节点初始化
tree.setEditable(true); //设置可以编辑节点名
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);//设置仅单选
tree.setShowsRootHandles(true);
//将树添加至面板
JScrollPane jsp = new JScrollPane(tree);
jsp.setPreferredSize(new Dimension(200, 405));
JPanel jpl = new JPanel();
jpl.add(jsp);
3.将TreeNode转化成String
&&TreeNode获得到的是一个列表,其中有各个节点的名字。应该是没有办法直接转换成路径的,我查了好多资料,所有就先转换成String然后在转换成File&&
TreeNode[] tn= node.getPath();
String path = tn[1].toString();
for(int i=2; i<tn.length; i++) {
path += tn[i] + "\\";
}
4.将TreePath转化成String
&&TreePath和TreeNode有点相似,但是TreePath无法逐一获取元素,需要先用函数getPath()转换成Object然后在转换成String&&
//path的类型是TreePath
Object tmp[] = path.getPath();
String tmp_path = tmp[1].toString();
for(int i=2; i<tmp.length; i++) {
tmp_path += tmp[i] + "\\";
}
5.事件处理中获取当前的节点
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) (e.getPath().getLastPathComponent());
}
6.直接使用updateUI()后,点击节点报错问题
&&多线程&&这里涉及到了多线程的知识&&
SwingUtilities.invokeLater(new Runnable(){
public void run(){
tree.updateUI();
}});
4.全部代码
【在对节点操作时,一定要先选中节点】
实现的节点操作功能:复制;粘贴;删除
希望大家不要完全抄录,有所思考,不会的地方,可以在下方评论,我会尽我可能解答,和大家一起学习!

gitee可下载源码:https://gitee.com/XiaoLuBanBi/codes/mqtvn5iaj8ehlbgorpwdx44
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File; import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.filechooser.FileSystemView;
import javax.swing.tree.*; /**
* 对节点进行操作时,一定要先选中节点
* @author a1126
*
*/
public class Src_manage extends JFrame
implements TreeSelectionListener, MouseListener, ActionListener {
//设置树结构
private JTree tree = new JTree();
private DefaultTreeModel treeModel;
private DefaultMutableTreeNode top;
//设置右击菜单项
private JPopupMenu jp = new JPopupMenu();
private JMenuItem copy = new JMenuItem("复制");
private JMenuItem paste = new JMenuItem("粘贴");
private JMenuItem delete = new JMenuItem("删除");
//设置复制黏贴临时存储
private File copy_path = null;
private File now_path = null;
private DefaultMutableTreeNode now_node = null; /**
* 构造函数
*/
public Src_manage() {
//设置布局
this.setLayout(new BorderLayout());
this.add(createPC(), BorderLayout.CENTER);
this.add(createPW(), BorderLayout.WEST);
ini_right_click();
//设置窗体
this.setSize(550, 450); //设置大小
this.setVisible(true); //设置窗体可见
this.setTitle("资源管理器"); //设置标题
this.setResizable(false); //设置不允许缩放
setLocationRelativeTo(null); //窗口居中
setDefaultCloseOperation(EXIT_ON_CLOSE);//窗口点击关闭时,退出程序
}
/**
* 设置西边面板
* @return
*/
public JPanel createPW() {
JPanel pw = new JPanel();
//设置树的模式,也可以不设置
top = new DefaultMutableTreeNode("我的电脑");
treeModel = new DefaultTreeModel(top);
//设置树
tree = new JTree(treeModel); //可以直接用节点初始化
tree.setEditable(true); //设置可以编辑节点名
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);//设置仅单选
tree.setShowsRootHandles(true);
//设置监听
tree.addTreeSelectionListener(this);
tree.addMouseListener(this);
//设置磁盘节点,加在top上
File roots[] = File.listRoots();
for(int i=0; i<roots.length; i++) {
top.add(new DefaultMutableTreeNode(roots[i]));
}
//添加至面板
JScrollPane jsp = new JScrollPane(tree);
jsp.setPreferredSize(new Dimension(200, 405));
pw.add(jsp);
//返回
return pw;
}
/**
* 设置中部面板
* @return
*/
public JPanel createPC() {
return new JPanel();
}
/**
* 创建节点
* @param path 文件路径
* @param node 默认节点
*/
public void createNode(File path, DefaultMutableTreeNode node) {
//如果是文件,则跳出
if(path.isFile())
return;
//否则,获取子文件,创建子节点
File childs[] = path.listFiles();
for(int i=0; i<childs.length; i++) {
//如果是隐藏文件,则跳过
if(childs[i].isHidden())
continue;
//根据文件名,创建节点
DefaultMutableTreeNode tmp = new DefaultMutableTreeNode(childs[i].getName());
//加入树中
treeModel.insertNodeInto(tmp, node, node.getChildCount());
//如果是文件夹,则创建空子节点(在后面会删掉)
if(childs[i].isDirectory())
tmp.add(new DefaultMutableTreeNode());
}
}
/**
* 初始化右键菜单
*/
public void ini_right_click() {
jp.add(copy);
jp.add(paste);
jp.add(delete);
copy.addActionListener(this);
paste.addActionListener(this);
delete.addActionListener(this);
}
/**
* 主函数
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成的方法存根
new Src_manage();
}
//选择节点时,往下更新子节点
@Override
public void valueChanged(TreeSelectionEvent e) {
// TODO 自动生成的方法存根
//获取选择的节点
DefaultMutableTreeNode node = (DefaultMutableTreeNode) (e.getPath().getLastPathComponent());
now_node = node;
//若为根节点,跳出
if(node.isRoot())
return;
//根据获取到的树中路径,创建磁盘绝对路径
TreeNode[] tp = node.getPath();
String path = tp[1].toString();
for(int i=2; i<tp.length; i++) {
path += tp[i] + "\\";
}
//删除子文件
node.removeAllChildren();
SwingUtilities.invokeLater(new Runnable(){
public void run(){
tree.updateUI();
}});//处理updateUI()抛空指针的问题
//调用 增加节点函数
createNode( new File(path), node);
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO 自动生成的方法存根
//获取右击点的节点路径
TreePath path = tree.getPathForLocation(e.getX(), e.getY());
//右击事件
if (e.getButton() == MouseEvent.BUTTON3 && path != null) {
// 确定当前节点
Object tmp[] = path.getPath();
if(tmp.length == 1) //如果获取的字符串长度为1,即是最上一层,则跳出
return;
String tmp_path = tmp[1].toString();
for(int i=2; i<tmp.length; i++) {
tmp_path += tmp[i] + "\\";
}
now_path = new File(tmp_path);
// 弹出菜单
jp.show(e.getComponent(), e.getX(), e.getY());
}
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO 自动生成的方法存根 }
@Override
public void mouseExited(MouseEvent e) {
// TODO 自动生成的方法存根 }
@Override
public void mousePressed(MouseEvent e) {
// TODO 自动生成的方法存根 }
@Override
public void mouseReleased(MouseEvent e) {
// TODO 自动生成的方法存根 }
/**
* 实现右键功能
*/
@Override
public void actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
if(e.getSource() == copy) { //复制按钮
copy_path = now_path;
}else if (e.getSource() == paste) { //粘贴按钮
now_node.add(new DefaultMutableTreeNode(copy_path.getName()));
//如果复制的节点下面还有子节点,也一起复制
if(copy_path.isDirectory())
createNode(copy_path, now_node);
}else if(e.getSource() == delete) { //删除按钮
treeModel.removeNodeFromParent(now_node);
}
}
}
JTree实现电脑资源管理器的更多相关文章
- 设置Win10文件资源管理器默认打开“这台电脑”
当Windows系统进入Win7之后,任务栏默认的文件资源管理器图标功能是“库”:Win8/Win8.1的这一按钮打开的是“这台电脑”.进入Win10之后,目前这一功能默认变为“快速访问”(曾经被称为 ...
- Jtree(节点的渲染+资源管理器)(2)
上一次我们建立一个比较简单的资源管理器,这次我们说一下上面的资源管理器的问题,并且得尽量的贴近windows的资源管理器. 这样一个简单的资源管理树就完成了,下面我们说说它的问题: ① 图片和外观和W ...
- 【win10】更改资源管理器显示:快速访问和此电脑
通常,我习惯通过按 win+E来打开资源管理器,然后显示各个分区并进行操作.在win10打开资源管理器默认显示的是快速访问,并不是显示的分区.下面是修改步骤. 1.按Win+E打开资源管理器,点击[查 ...
- WPF 选择电脑文件显示路径,弹出资源管理器,打开文件
选择文件,将路径显示在名为txbx的textbox上 // 在WPF中, OpenFileDialog位于Microsoft.Win32名称空间 Microsoft.Win32.OpenFileDia ...
- win7使用自带资源管理器来登陆FTP
使用windows自带的资源管理器登陆FTP,其实很简单,打开计算机,在地址栏直接输入ftp://ftp.hostname即可. 但是这种方式需要每次输入ip地址,还要输入用户名和密码,比较麻烦.可能 ...
- HDFS分布式文件系统资源管理器开发总结
HDFS,全称Hadoop分布式文件系统,作为Hadoop生态技术圈底层的关键技术之一,被设计成适合运行在通用硬件上的分布式文件系统.它和现有的分布式文件系统有很多共同点,但同时,它和其他的分布式 ...
- 20160223 - Windows 10 的文件资源管理器下出现重复文件夹的解决办法
现象: 安装 OneDrive 从 Windows 7.8.8.1 升级来的 Windows 10 的电脑,可能会出现文件资源管理器左侧面板中出现重复的文件夹. 通常有:视频.图片.文档.下载.音频. ...
- 初识IO流之小型资源管理器
初次接触到IO流,根据书本上的知识,加上自己的摸索,发现了一些好玩的事情.(书本上的知识或多或少,有时候不足以解决我们的问题!这时候我们就应该自己去求解!!! 所以我们学习的时候要抱有探索的精神,求知 ...
- Linux的资源管理器
说是资源管理器,其实就是使用命令来对Linux运行系统的参数的查看.下面就一起看一看怎么像在windows下查看资源管理器吧. 1.查看进程(额,自然是电脑上正在运行的进程咯) ps aux 其中a ...
随机推荐
- 01-urllib库添加headers的一般方法
2018-08-23 13:07:57 对于请求一些网站,我们需要加上请求头才可以完成网页的抓取,不然会得到一些错误,无法返回抓取的网页.下面,介绍两种添加请求头的方法. 方法一:借助build_op ...
- 2、基于wsgiref模块DIY一个web框架
一 web框架 Web框架(Web framework)是一种开发框架,用来支持动态网站.网络应用和网络服务的开发.这大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方 ...
- Ubuntu18.04 使用过程遇到的问题记录
索引: 1.Ubuntu 18.04 安装搜狗输入法 2.在 Ubuntu 18.04 中将第三方软件添加至 favorite 菜单栏 3.在 VMware workstation 中为虚拟机安装 V ...
- FreeMarker标签使用
FreeMarker标签使用 模板技术在现代的软件开发中有着重要的地位,主要用于view层的展示,freemarker是比较流行的一种. 一.FreeMarker模板文件主要有4个部分组成 ①文本,直 ...
- SGU---102 欧拉函数
题目链接: https://cn.vjudge.net/problem/SGU-102#author=0 题目大意: 求解小于等于N的且与N互质的数字有多少个 解题思路: 直接求欧拉函数即可 关于欧拉 ...
- iOS 开源库系列 Aspects核心源码分析---面向切面编程之疯狂的 Aspects
Aspects的源码学习,我学到的有几下几点 Objective-C Runtime 理解OC的消息分发机制 KVO中的指针交换技术 Block 在内存中的数据结构 const 的修饰区别 block ...
- JSP九大内置对象和四大作用域和Servlet的三大作用域对象
一.JSP九大内置对象:内置对象(又叫隐含对象,有9个内置对象):不需要预先声明就可以在脚本代码和表达式中随意使用 内置对象特点: 由JSP规范提供,不用编写者实例化. 通过Web容器实现和管理 所有 ...
- 创建JDBCUtils工具类
JDBCUtils工具类 私有化构造函数,外界无法直接创建对象 提供公共的,静态的,getConnection 方法,用来给外界提供数据库连接 提供公共的,静态的,close方法,用来释放资源 pac ...
- centos6.5升级内核到3.0
因为是使用centos6.5安装的docker,而docker需要内核3.0以上的支持,所以必须升级内核 1. 导入public key rpm --import https://www.elrepo ...
- 微信公众号开发 [03] 结合UEditor实现图文消息群发功能
0.写在前面的话 如何实现微信平台后台管理中的,图文消息发送功能? 大概的过程如下: 通过类似表单的形式,将文章各部分内容提交到后台,封装成一个实体类,并持久化到数据库中 需要推送的时候,将不同的文章 ...