一般情况下,构建一个
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[i].getName(),
files[i].getAbsolutePath(),files[i].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[i].getName(), files[i].getAbsolutePath(),files[i].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:/");
}
}
当然可以进一步实现界面的易用性,就是在初始点击之后,加载完之前,让鼠标变成等待的形状。
posted on 2007-10-30 16:22
蒋家狂潮 阅读(1529)
评论(1) 编辑 收藏 所属分类:
Swing