1.前期调查:
经生活常识可知Windows文件管理器的文件列表是树状结构,因此推想到JTree组件创建目录树也做一个树形结构的文件浏览器
功能架构图:
2.实现功能:对文件目录进行查看浏览,创建文件目录树
3.代码
1 package event; 2 import java.awt.BorderLayout; 3 import java.awt.Component; 4 import java.io.File; 5 import java.util.*; 6 import javax.swing.*; 7 import javax.swing.border.EmptyBorder; 8 import javax.swing.event.TreeSelectionEvent; 9 import javax.swing.event.TreeSelectionListener;//监听接口,接口表示树选择组件的当前状态 10 import javax.swing.filechooser.FileSystemView;//系统视图 11 import javax.swing.tree.DefaultMutableTreeNode;//存储树节点数据 12 import javax.swing.tree.DefaultTreeCellRenderer;//树节点渲染器 13 import javax.swing.tree.TreeNode; 14 import ui.MainForm; 15 @SuppressWarnings({ "serial", "unused" }) 16 public class FilesTree extends JPanel { //FilesTree程序主窗口 17 protected static FileSystemView fsv = FileSystemView.getFileSystemView(); //系统视图 18 public static class FileTreeCellRenderer extends DefaultTreeCellRenderer { //文件树的渲染器 19 private Map<String, Icon> iconCache = new HashMap<String, Icon>();////缓存图标加速渲染 20 private Map<File, String> rootNameCache = new HashMap<File, String>();//缓存根名加速渲染 21 @SuppressWarnings("null") 22 public Icon[] GetFileIcons(String path){ 23 Icon[] icons = null; 24 String[] files = GetFileNames.getFileName(path); 25 for(int i = 0; i < files.length; ++i){ 26 icons[i] = this.iconCache.get(files[i]); 27 } 28 return icons;//返回图标 29 } 30 31 @Override 32 public Component getTreeCellRendererComponent(JTree tree, Object value,boolean sel, boolean expanded, boolean leaf, int row,boolean hasFocus) {//设置节点图标 33 FileTreeNode ftn = (FileTreeNode) value; 34 File file = ftn.file; 35 String filename = ""; 36 if (file != null) { 37 if (ftn.isFileSystemRoot) { 38 filename = this.rootNameCache.get(file); 39 if (filename == null) { 40 filename = fsv.getSystemDisplayName(file); 41 this.rootNameCache.put(file, filename); 42 } 43 } else { 44 filename = file.getName(); 45 } 46 } 47 JLabel result = (JLabel) super.getTreeCellRendererComponent(tree, 48 filename, sel, expanded, leaf, row, hasFocus); 49 if (file != null) { 50 Icon icon = this.iconCache.get(filename); 51 if (icon == null) { 52 icon = fsv.getSystemIcon(file); 53 this.iconCache.put(filename, icon); 54 } 55 result.setIcon(icon); 56 } 57 return result; 58 } 59 } 60 61 62 private static class FileTreeNode implements TreeNode { 63 64 private File file;//定义File类型的节点 65 66 private File[] children;//孩子节点 67 68 private TreeNode parent;//父亲节点 69 70 private boolean isFileSystemRoot;//判断此节点是否对应于文件系统根目录 71 72 public FileTreeNode(File file, boolean isFileSystemRoot, TreeNode parent) { //定义File类型的节点,判断文件是否为文件系统根目录,父亲节点 73 this.file = file; 74 this.isFileSystemRoot = isFileSystemRoot; 75 this.parent = parent; 76 this.children = this.file.listFiles(); 77 if (this.children == null) 78 this.children = new File[0]; 79 } 80 81 public String toString(){ 82 if(file != null) 83 return file.getAbsolutePath(); 84 else 85 return ""; 86 } 87 88 public FileTreeNode(File[] children) { //创建新的孩子节点 89 this.file = null; 90 this.parent = null; 91 this.children = children; 92 } 93 94 @SuppressWarnings("unchecked") 95 public Enumeration<? extends TreeNode> children() { 96 final int elementCount = this.children.length; 97 return (Enumeration<? extends TreeNode>) new Enumeration<File>() { 98 int count = 0; 99 public boolean hasMoreElements() { 100 return this.count < elementCount; 101 } 102 public File nextElement() { 103 if (this.count < elementCount) { 104 return FileTreeNode.this.children[this.count++]; 105 } 106 throw new NoSuchElementException("Vector Enumeration"); 107 } 108 }; 109 110 } 111 112 public boolean getAllowsChildren() { //如果允许接收孩子,则返回 true 113 return true; 114 } 115 116 public TreeNode getChildAt(int childIndex) { 117 return new FileTreeNode(this.children[childIndex], 118 this.parent == null, this); 119 } 120 121 public int getChildCount() { //返回孩子的个数 122 return this.children.length; 123 } 124 125 public int getIndex(TreeNode node) { 126 FileTreeNode ftn = (FileTreeNode) node; 127 for (int i = 0; i < this.children.length; i++) { 128 if (ftn.file.equals(this.children[i])) 129 return i; 130 } 131 return -1; 132 } 133 134 public TreeNode getParent() { 135 return this.parent; 136 } 137 138 139 public boolean isLeaf() { 140 return (this.getChildCount() == 0); 141 } 142 } 143 144 private JTree tree; 145 //创建文件树面板 146 public FilesTree() { 147 this.setLayout(new BorderLayout()); 148 File[] roots = File.listRoots(); 149 FileTreeNode rootTreeNode = new FileTreeNode(roots); 150 this.tree = new JTree(rootTreeNode); 151 this.tree.setCellRenderer(new FileTreeCellRenderer()); 152 this.tree.setRootVisible(false); 153 this.tree.addTreeSelectionListener(new TreeSelectionListener() { 154 public void valueChanged(TreeSelectionEvent e) { 155 if(tree.getLastSelectedPathComponent() == null) return; 156 String chooseUrl = tree.getLastSelectedPathComponent().toString(); 157 File temp_file = new File(chooseUrl); 158 if(temp_file.isDirectory()){ 159 MainForm._instance.stack.push(MainForm._instance.Cur_URL); 160 MainForm._instance.Cur_URL = chooseUrl; 161 MainForm._instance.Go_There(); 162 } 163 // System.out.println("我点击的节点的值:" + tree.getLastSelectedPathComponent().toString()); 164 } 165 }); 166 final JScrollPane jsp = new JScrollPane(this.tree);//可滚动 167 jsp.setBorder(new EmptyBorder(0, 0, 0, 0)); 168 this.add(jsp, BorderLayout.CENTER); 169 } 170 171 public static void main(String[] args) { 172 SwingUtilities.invokeLater(new Runnable() { 173 public void run() { 174 JFrame frame = new JFrame("File tree"); 175 frame.setSize(500, 400); 176 frame.setLocationRelativeTo(null); 177 frame.add(new FilesTree()); 178 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 179 frame.setVisible(true); 180 } 181 }); 182 } 183 }
4.运行截图
5.遇到的问题和代码改进:
代码有些冗余且小问题较多做程序的过程中有些仓促和出差错,暴露出了平时练习的问题,今后会多多加强各种语言的学习改进自身水平;
本次课程设计在团队的分工合作下,做了各自负责的功能,我第一次知道和使用tree.setCellRenderer(new TreeNodeRenderer())即树节点渲染器的代码,另外对Enumeration枚举类应用不熟,借此机会学到了很多方法和命名空间,另外JTree的实现JScrollPane,JPanel,JFrame缺一不可,实践加深了我对java jTree组件、swing组件、GUI界面的应用学习,学会用jTree遍历文件,jList多行显示,java.io.file对文件的操作,编写代码的安全性屡屡发出警告也提醒督促我更规范地用编程语言写程序,并且意识到实现一个功能需要调用很多方法并不那么容易,有些问题通过询问小组成员解决,最终方案出来前我们小组也腾讯会议商讨了几次如何完善运行界面使搜索速率更快,虽然这个程序或许不那么完善,但是我们都努力自主地做了,提醒我将来做其他项目的时候一定要有更充足的准备