TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
一般情况下,构建一个 SWING 树,都是先要构建好存放数据的模型 (TreeModel), 一般情况下,实现起来都没有问题,但当数据量非常大的时候,一次性构建好 TreeModel ,将会花费很多时间,界面处于灰掉的状态(当然可以另开其他线程,可以操作其他界面),这个给用户的感觉非常差。解决这个问题的关键在于,树模型的数据。我们都知道,系统文件是一层一层很有层次性,这样我们就可以以一个文件(不管是文件还是文件夹)为树节点,当初次加载树的时候,点击树节点,先判断其有没有子节点,若无,就去读该节点的文件信息并保存,若为文件夹,就去取其文件夹下的所有文件,构造出树节点,加到树中。第二次点击的时候,就不会去读磁盘文件系统了。
代码清单: import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import java.io.*; import java.awt.*; import javax.swing.*; import javax.swing.tree.TreeCellRenderer; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.tree.TreePath; /** * <p>Title: JDHSystemFileTree</p> * <p>Description: 系统目录树,动态生成,解决载入慢的问题 </p> * <p>Copyright: Copyright (c) 2007</p> * @author 蒋家狂潮 * @version 1.0 */ public class SystemFileTree { private DefaultTreeModel model; private JTree tree; public SystemFileTree () { JFrame f=new JFrame(); f.getContentPane().setLayout(new BorderLayout()); tree=new JTree(); tree.addMouseListener(new MouseAdapter(){ public void mousePressed(MouseEvent e){ node_mouseAction(e); } }); JScrollPane scroll=new JScrollPane(tree); f.getContentPane().add(scroll,BorderLayout.CENTER);
f.setLocation(250,250); f.setSize(new Dimension(300,500)); f.setVisible(true); } private void node_mouseAction(MouseEvent e){ int row = tree.getRowForLocation(e.getX(), e.getY()); PathNode pathNode =null; if(row != -1){ TreePath path = tree.getPathForRow(row); pathNode = (PathNode)path.getLastPathComponent();
if(pathNode.isFolder()&&pathNode.getChildCount()==0){ builderNode(pathNode); tree.expandPath(path); } }
} private PathNode builderNode(PathNode pathNode){ String filePath= pathNode.getValue().toString(); File file=new File(filePath); File[] files=file.listFiles(); for(int i=0;i<files.length;i++){ PathNode node=new PathNode(files.getName(), files.getAbsolutePath(),files.isDirectory()); pathNode.add(node); } return pathNode; } private void initData(String rootPath){
File f=new File(rootPath);
PathNode root=new PathNode(f.getName(), rootPath,f.isDirectory());
File[] files=f.listFiles(); for(int i=0;i<files.length;i++){ PathNode node=
new PathNode(files.getName(), files.getAbsolutePath(),files.isDirectory()); root.add(node); }
model=new DefaultTreeModel(root); tree.setModel(model); FileTreeRenderer renderer=new FileTreeRenderer(); tree.setCellRenderer(renderer); tree.repaint(); }
class FileTreeRenderer implements TreeCellRenderer{ private Icon folder_open=new ImageIcon("icons/folder_open.jpg"); private Icon folder_close=new ImageIcon("icons/folder_close.jpg"); private Icon file=new ImageIcon("icons/file.gif"); public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { JLabel label = null; if (value != null) { System.out.println(value.getClass().toString()); if(value instanceof PathNode){
PathNode pathNode = (PathNode) value; if (pathNode.isFolder()) { if (expanded) { label = new JLabel(pathNode.getUserObject(). toString(), folder_open, JLabel.RIGHT); } else if(!expanded||leaf) { label = new JLabel(pathNode.getUserObject(). toString(), folder_close, JLabel.RIGHT); } } else { label = new JLabel(pathNode.getUserObject().toString(), file, JLabel.RIGHT); } return label; } } return label; } }
class PathNode extends DefaultMutableTreeNode{ Object value; boolean isFolder; public PathNode(String name,Object value,boolean isFolder){ super(name); this.value=value; this.isFolder=isFolder; } public Object getValue(){ return value; } public boolean isFolder(){ return isFolder; } } public static void main(String args[]){ JDHSystemFileTree tree=new JDHSystemFileTree(); // 给个路径作演示 tree.initData("D:/"); } }
当然可以进一步实现界面的易用性,就是在初始点击之后,加载完之前,让鼠标变成等待的形状。
源码下载:http://file.javaxxz.com/2014/10/31/235543312.zip |
|