GUI 文件管理器


https://github.com/ifrozenwhale/file_manager

文件管理器

各模块功能实现

功能实现

  • 界面跳转:
  1. 后退,逐级返回到父级目录。
  2. 前进,按照后退的顺序依次进入子目录。
  3. 当前目录路径显示,输入目录地址进行跳转。
  • 界面显示:
  1. 文件目录树显示(只显示文件夹)。
  2. 文件列表显示(只显示当前目录下的文件夹和文件),带有系统图标。
  3. 点击文件树中的结点,在文件列表同步显示。
  • 选择与打开
  1. 支持多选,选中文件高亮显示,点击空白区域取消选中。
  2. 单击文件夹进入,单击文件打开应用。
  • 右键选中文件
  1. 批量复制,包括所有子目录和文件。
  2. 批量压缩,格式为zip,将多个文件压缩成一个,自定义命名。
  3. 单文件加密,自定义加密密钥。
  • 右键空白区域
  1. 创建文件夹,自定义命名;
  2. 批量粘贴,粘贴的目录不能是源文件目录的子目录;
  3. 批量解压,解压到当前目录下。
  4. 单文件解密,输入加密密钥,若密钥不正确,加密后的文件仍无法打开。

算法设计

主要是FileModel的实现

数据记录

  • List<File> defaultListModelFile currentFile负责记录当前目录和目录下的文件、文件夹。

初始化

  • initRoots方法,将磁盘目录,如C:\D:\E:\添加进文件列表。

文件更新

  • updateModels(File file)方法,将当前文件设为file,并将其当前目录层级下的文件(夹)添加进文件列表。

前进和后退

  1. redoStack负责记录操作路径,undo时,得到父级目录下文件和文件夹,更新文件列表,并将文件压入redoStack
  2. redo时,弹出栈顶文件,更新当前文件列表。
  3. 细节,如果父级为null,说明当前是磁盘根目录,如D:\,则调用初始化方法initRoots

文件复制

  1. copySources负责存储粘贴板中的文件。
  2. 选中文件后,加入到copySources中。
  3. 粘贴时,判断是文件,还是文件夹
    1. 如果是文件,则进行文件复制。
    2. 如果是文件夹,递归调用。
  4. 异常处理,粘贴的目录不能是源目录的子目录,由isParent进行判断。

创建和删除

  1. 如果不存在,则创建。
  2. 递归删除,由deleteHelp负责递归,如果删除的是文件夹,就递归调用,最终删除根文件。
  3. 对选中的文件遍历执行,批量删除。

压缩和解压

  1. 对于文件,直接压缩。
  2. 对于文件夹,递归压缩。

文件加密和解密

  1. 对文件读取字节内容,与密钥进行简单的异或加密。
  2. 加密后得到新文件,删除原始文件,并将新文件重命名为原文件。(也可以不删除,防止出问题,重要文件)
  3. 解密的时候,与加密过程相同,输入密钥,读取文件,异或解密。

取消选中

  1. 重写locationToIndex函数,判断点击的位置是否有效

    java
    int index = super.locationToIndex(location);        
    if (index != -1 && !getCellBounds(index, index).contains(location))	return -1;

样式渲染

  1. 实现FileListCellRenderer类继承DefaultListCellRenderer
  2. 设置图标,设置显示信息,磁盘根目录使用getPath(),其他目录使用getName()
  3. 选中设置颜色,取消选中恢复之前的颜色。

文件树展开

  1. 实现TreeSelectionListener接口,采用延迟加载,即每次点击展开时再加载目录文件。

软件调试分析

执行过程

  1. 启动App类的main函数

  2. FileController初始化的时候,完成对数据成员的初始化,包括添加事件监听,更新初始视图。

    java
    public FileController(App app, FileModel fileModel, FileTreeModel treeModel) {
            this.fileDisplay = app.getFileDisplay();
            this.app = app;
            this.fileModel = fileModel;
            this.filesTree = app.getFilesTree();
            this.treeModel = treeModel;
            // 添加事件监听
            fileDisplay.addCopyListener(new CopyListener());
            fileDisplay.addCreateListener(new CreateFileListener());
            fileDisplay.addPasteListener(new PasteListener());
            fileDisplay.addUnzipListener(new UnZipListener());
            fileDisplay.addZipListener(new ZipListener());
            fileDisplay.addDeleteListener(new DeleteListener());
            fileDisplay.addMyMouseListener(new FileClickListener());
            fileDisplay.addEncodeListener(new EncodeListener());
            fileDisplay.addDecodeListener(new DecodeListener());
            app.addUndoListener(new UndoListener());
            app.addRedoListener(new RedoListener());
            app.addGoListener(new GoListener());
            filesTree.addTreeSelectionListener(new FileTreeSelListener());
            filesTree.setRootVisible(false);
            // 初始化主视图
            fileDisplay.updateView(fileModel.getDefaultListModel());
        }
  3. 监听到事件发生,调用modelview进行逻辑实现并更新视图。例如,展开文件目录树时,需要对三部分视图进行更新(文件树,文件列表,url地址栏)

    java
    class FileTreeSelListener implements TreeSelectionListener {
        @Override
        public void valueChanged(TreeSelectionEvent e) {
            File file = filesTree.getCurrentFile(); // 得到点击的文件结点
            // 加载目录树
            filesTree.loadingTree((DefaultMutableTreeNode)
            	filesTree.getLastSelectedPathComponent(), treeModel.getFiles(file));
            // 更新文件数据模型
            fileModel.updateModels(file);
            // 更新文件列表视图
            fileDisplay.updateView(fileModel.getDefaultListModel());
            // 更新url地址显示
            String url = fileModel.getUrl();
            app.updateUrl(url);
        }
    }

    再如,undo操作时,model进行undo,更新数据,然后视图更新

    java
    class UndoListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            fileModel.undo(); // 数据模型更新
            fileDisplay.updateView(fileModel.getDefaultListModel()); // 列表视图更新
            String url = fileModel.getUrl(); 
            app.updateUrl(url); // url地址栏更新
        }
    }

界面展示

主界面

主界面
主界面

  • 上侧可以后撤、前进,url地址栏显示
  • 左侧目录树展开,并同步更新右侧文件列表

文件及文件夹拷贝

拷贝
拷贝

右键粘贴,将子目录下所有文件(夹)粘贴

解压压缩

压缩
压缩


文章作者: frozenwhale
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 frozenwhale !
 上一篇
网络协议封装 网络协议封装
在 Linux 上使用 C 语言在数据链路层上通信,实现Ethernet,IPv4 和 UDP 协议以及应用层封装。
2022-09-03
下一篇 
CQU-Face CQU-Face
基于百度API的人脸检测与分析,并语音播报。支持图片上传/即时拍照人脸特征分析展示,分析报告分享、发现、点赞、评论,用户关注、收藏等, 历史记录查询和编辑, 登录/未登录身份权限控制等。
2022-09-03