JTree实现电脑资源管理器

0.前言

  最近老师布置了一项用Java写资源管理器的任务,一开始觉得简单,可是实际操做起来,却发现网上的资源用起来相对生疏。在使用中,我也遇到了许多问题,虽然不能像其余博主同样,写的很是齐全,但我仍是分享一下我写的代码。java

1.准备知识

  • JTree是树形结构,是咱们作资源管理器的必要组件。其构造函数的参数能够是节点,或者树模型。
  • JTree只有放在JScrollPane里,才能够很好的显示(由于有时候树很大,要拉很长才能看到),固然不放也能够。
  • JTree是经过增长节点,来实现多层目录的。
  • 通常使用DefaultMutableTreeNode来实现节点,能够经过add()函数,添加孩子节点。
  • 还有些琐碎的知识点,会在第三部分一一讲述。

2.思路

  一开始的思路是用DFS深搜,可是实现后发现,至关的慢。node

  因此,我就想先写一个“个人电脑”节点,而后往下加磁盘分区,而后当我点击一个节点的时候(用事件监听,这里用到TreeSelectionListener),再往下展开(添加节点)git

3.分段代码

  1.获取系统的磁盘目录

1 //获取磁盘目录
2 File roots[] = File.listRoots(); 3 //添加至父节点
4 for(int i=0; i<roots.length; i++) { 5     father_node.add(new DefaultMutableTreeNode(roots[i])); 6 }

  2.设置一颗无缺的树,并加入面板

  &&强调&&必定要先把Tree设置好以后,再添加至JScrollPane上,不然可能会出现无显示的状况&&多线程

 1 //设置树的模式,也能够不设置
 2 DefaultMutableTreeNode top_node= new DefaultMutableTreeNode("个人电脑");  3 DefaultTreeModel treeModel = new DefaultTreeModel(top);  4 //设置树
 5 JTree tree = new JTree(treeModel);        //能够直接用节点初始化 
 6 tree.setEditable(true);                //设置能够编辑节点名 
 7 tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);//设置仅单选
 8 tree.setShowsRootHandles(true);  9 //将树添加至面板
10 JScrollPane jsp = new JScrollPane(tree); 11 jsp.setPreferredSize(new Dimension(200, 405)); 12 JPanel jpl = new JPanel(); 13 jpl.add(jsp);

   3.将TreeNode转化成String

  &&TreeNode得到到的是一个列表,其中有各个节点的名字。应该是没有办法直接转换成路径的,我查了好多资料,全部就先转换成String而后在转换成File&&jsp

1 TreeNode[] tn= node.getPath(); 2 String path = tn[1].toString(); 3 for(int i=2; i<tn.length; i++) { 4     path += tn[i] + "\\"; 5 }

  4.将TreePath转化成String

  &&TreePath和TreeNode有点类似,可是TreePath没法逐一获取元素,须要先用函数getPath()转换成Object而后在转换成String&&ide

1 //path的类型是TreePath
2 Object tmp[] = path.getPath(); 3 String tmp_path = tmp[1].toString(); 4 for(int i=2; i<tmp.length; i++) { 5     tmp_path += tmp[i] + "\\"; 6 }

   5.事件处理中获取当前的节点

1 public void valueChanged(TreeSelectionEvent e) { 2     DefaultMutableTreeNode node = (DefaultMutableTreeNode) (e.getPath().getLastPathComponent()); 3 }

   6.直接使用updateUI()后,点击节点报错问题

  &&多线程&&这里涉及到了多线程的知识&&函数

1 SwingUtilities.invokeLater(new Runnable(){ 2 public void run(){ 3  tree.updateUI(); 4 }});

 

4.所有代码

  【在对节点操做时,必定要先选中节点】布局

  实现的节点操做功能:复制;粘贴;删除学习

  但愿你们不要彻底抄录,有所思考,不会的地方,能够在下方评论,我会尽我可能解答,和你们一块儿学习!this

  gitee可下载源码:https://gitee.com/XiaoLuBanBi/codes/mqtvn5iaj8ehlbgorpwdx44

 1 import java.awt.*;  2 import java.awt.event.ActionEvent;  3 import java.awt.event.ActionListener;  4 import java.awt.event.MouseEvent;  5 import java.awt.event.MouseListener;  6 import java.io.File;  7 
 8 import javax.swing.*;  9 import javax.swing.event.TreeSelectionEvent;  10 import javax.swing.event.TreeSelectionListener;  11 import javax.swing.filechooser.FileSystemView;  12 import javax.swing.tree.*;  13 
 14 /**
 15  * 对节点进行操做时,必定要先选中节点  16  * @author a1126  17  *  18  */
 19 public class Src_manage extends JFrame  20                 implements TreeSelectionListener, MouseListener, ActionListener {  21     //设置树结构
 22     private JTree tree = new JTree();  23     private DefaultTreeModel treeModel;  24     private DefaultMutableTreeNode top;  25     //设置右击菜单项
 26     private JPopupMenu jp = new JPopupMenu();  27     private JMenuItem copy = new JMenuItem("复制");  28     private JMenuItem paste = new JMenuItem("粘贴");  29     private JMenuItem delete = new JMenuItem("删除");  30     //设置复制黏贴临时存储
 31     private File copy_path = null;  32     private File now_path = null;  33     private DefaultMutableTreeNode now_node = null;  34     
 35     /**
 36  * 构造函数  37      */
 38     public Src_manage() {  39         //设置布局
 40         this.setLayout(new BorderLayout());  41         this.add(createPC(), BorderLayout.CENTER);  42         this.add(createPW(), BorderLayout.WEST);  43  ini_right_click();  44         //设置窗体
 45         this.setSize(550, 450);                    //设置大小
 46         this.setVisible(true);                    //设置窗体可见
 47         this.setTitle("资源管理器");                //设置标题
 48         this.setResizable(false);                //设置不容许缩放
 49         setLocationRelativeTo(null);            //窗口居中
 50         setDefaultCloseOperation(EXIT_ON_CLOSE);//窗口点击关闭时,退出程序
 51  }  52     /**
 53  * 设置西边面板  54  * @return
 55      */
 56     public JPanel createPW() {  57         JPanel pw = new JPanel();  58         //设置树的模式,也能够不设置
 59         top = new DefaultMutableTreeNode("个人电脑");  60         treeModel = new DefaultTreeModel(top);  61         //设置树
 62         tree = new JTree(treeModel);        //能够直接用节点初始化
 63         tree.setEditable(true);                //设置能够编辑节点名
 64         tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);//设置仅单选
 65         tree.setShowsRootHandles(true);  66         //设置监听
 67         tree.addTreeSelectionListener(this);  68         tree.addMouseListener(this);  69         //设置磁盘节点,加在top上
 70         File roots[] = File.listRoots();  71         for(int i=0; i<roots.length; i++) {  72             top.add(new DefaultMutableTreeNode(roots[i]));  73  }  74         //添加至面板
 75         JScrollPane jsp = new JScrollPane(tree);  76         jsp.setPreferredSize(new Dimension(200, 405));  77  pw.add(jsp);  78         //返回
 79         return pw;  80  }  81     /**
 82  * 设置中部面板  83  * @return
 84      */
 85     public JPanel createPC() {  86         return new JPanel();  87  }  88     /**
 89  * 建立节点  90  * @param path 文件路径  91  * @param node 默认节点  92      */
 93     public void createNode(File path, DefaultMutableTreeNode node) {  94         //若是是文件,则跳出
 95         if(path.isFile())  96             return;  97         //不然,获取子文件,建立子节点
 98         File childs[] = path.listFiles();  99         for(int i=0; i<childs.length; i++) { 100             //若是是隐藏文件,则跳过
101             if(childs[i].isHidden()) 102                 continue; 103             //根据文件名,建立节点
104             DefaultMutableTreeNode tmp = new DefaultMutableTreeNode(childs[i].getName()); 105             //加入树中
106  treeModel.insertNodeInto(tmp, node, node.getChildCount()); 107             //若是是文件夹,则建立空子节点(在后面会删掉)
108             if(childs[i].isDirectory()) 109                 tmp.add(new DefaultMutableTreeNode()); 110  } 111  } 112     /**
113  * 初始化右键菜单 114      */
115     public void ini_right_click() { 116  jp.add(copy); 117  jp.add(paste); 118  jp.add(delete); 119         copy.addActionListener(this); 120         paste.addActionListener(this); 121         delete.addActionListener(this); 122  } 123     /**
124  * 主函数 125  * @param args 126      */
127     public static void main(String[] args) { 128         // TODO 自动生成的方法存根
129         new Src_manage(); 130  } 131     //选择节点时,往下更新子节点
132  @Override 133     public void valueChanged(TreeSelectionEvent e) { 134         // TODO 自动生成的方法存根 135         //获取选择的节点
136         DefaultMutableTreeNode node = (DefaultMutableTreeNode) (e.getPath().getLastPathComponent()); 137         now_node = node; 138         //若为根节点,跳出
139         if(node.isRoot()) 140             return; 141         //根据获取到的树中路径,建立磁盘绝对路径
142         TreeNode[] tp = node.getPath(); 143         String path = tp[1].toString(); 144         for(int i=2; i<tp.length; i++) { 145             path += tp[i] + "\\"; 146  } 147         //删除子文件
148  node.removeAllChildren(); 149         SwingUtilities.invokeLater(new Runnable(){ 150             public void run(){ 151  tree.updateUI(); 152         }});//处理updateUI()抛空指针的问题 153         //调用 增长节点函数
154         createNode( new File(path), node); 155  } 156  @Override 157     public void mouseClicked(MouseEvent e) { 158         // TODO 自动生成的方法存根 159         //获取右击点的节点路径
160         TreePath path = tree.getPathForLocation(e.getX(), e.getY()); 161         //右击事件
162         if (e.getButton() == MouseEvent.BUTTON3 && path != null) { 163             // 肯定当前节点
164             Object tmp[] = path.getPath(); 165             if(tmp.length == 1)    //若是获取的字符串长度为1,便是最上一层,则跳出
166                 return; 167             String tmp_path = tmp[1].toString(); 168             for(int i=2; i<tmp.length; i++) { 169                 tmp_path += tmp[i] + "\\"; 170  } 171             now_path = new File(tmp_path); 172             // 弹出菜单
173  jp.show(e.getComponent(), e.getX(), e.getY()); 174  } 175  } 176  @Override 177     public void mouseEntered(MouseEvent e) { 178         // TODO 自动生成的方法存根
179         
180  } 181  @Override 182     public void mouseExited(MouseEvent e) { 183         // TODO 自动生成的方法存根
184         
185  } 186  @Override 187     public void mousePressed(MouseEvent e) { 188         // TODO 自动生成的方法存根
189         
190  } 191  @Override 192     public void mouseReleased(MouseEvent e) { 193         // TODO 自动生成的方法存根
194         
195  } 196     /**
197  * 实现右键功能 198      */
199  @Override 200     public void actionPerformed(ActionEvent e) { 201         // TODO 自动生成的方法存根
202         if(e.getSource() == copy) {    //复制按钮
203             copy_path = now_path; 204         }else if (e.getSource() == paste) {    //粘贴按钮
205             now_node.add(new DefaultMutableTreeNode(copy_path.getName())); 206             //若是复制的节点下面还有子节点,也一块儿复制
207             if(copy_path.isDirectory()) 208  createNode(copy_path, now_node); 209         }else if(e.getSource() == delete) {    //删除按钮
210  treeModel.removeNodeFromParent(now_node); 211  } 212  } 213 }
相关文章
相关标签/搜索