zoukankan      html  css  js  c++  java
  • JTree实现电脑资源管理器

    0.前言

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

    1.准备知识

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

    2.思路

      一开始的思路是用DFS深搜,但是实现后发现,相当的慢。

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

    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&&

    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&&

    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.全部代码

      【在对节点操作时,一定要先选中节点】

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

      希望大家不要完全抄录,有所思考,不会的地方,可以在下方评论,我会尽我可能解答,和大家一起学习!

      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 }
  • 相关阅读:
    仿新浪首页、主题、详情页,纯html静态页面
    hdoj 4790 Just Random 【数学】
    Codeforces 97B Superset 平面分治
    HDU 1017 A Mathematical Curiosity【看懂题意+穷举法】
    Codeforces Round #221 (Div. 2) D
    一个bug在redmine中的诞生到终结
    hi3531 SDK已编译文件系统制作jffs2文件系统镜像并解决这个问题 .
    js前端3des加密 后台java解密
    进程经常使用小知识汇总
    泛型集合的使用
  • 原文地址:https://www.cnblogs.com/Lu-Yuyang/p/9955938.html
Copyright © 2011-2022 走看看