swing JTree懒加载本地资源目录

使用swing的JTree加载本地资源目录,当本地文件和文件夹比较多时加载速度会很慢,故使用懒加载的方式以提高加载速度。
先只加载一层目录和文件,当点击展开目录时再加载它的子节点。
实现代码如下:

import java.io.File;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.ExpandVetoException;

/**
 * 懒加载本地资源目录
 * @author dqk
 *
 * @date 2022年11月4日
 */
public class LoadLazyTree {

	public static void main(String[] args) {
		openWindow();
	}

	private static void openWindow() {
		  JFrame jFrame = new JFrame();
		  File[] listRoots = File.listRoots();
		  // 递归构建文件树的根节点
	      DefaultMutableTreeNode rootNode = buildrootNode(listRoots);
	      DefaultTreeModel defaultTreeModel = new DefaultTreeModel(rootNode);
	      //将加载的节点设置成“询问是否有子节点”,DefaultMutableTreeNode.setAllowsChildren(false);时节点为叶节点,也就是没有子节点
	      defaultTreeModel.setAsksAllowsChildren(true);
	      // 使用根节点去初始化一颗树
	      JTree fileBrowserTree = new JTree(defaultTreeModel);
	      JScrollPane jScrollPane = new JScrollPane(fileBrowserTree);
	      //树节点将要展开或者关闭时
	      fileBrowserTree.addTreeWillExpandListener(new TreeWillExpandListener() {
	      	//节点将要展开时触发
				@Override
				public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
					DefaultMutableTreeNode defaultMutableTreeNode = (DefaultMutableTreeNode)event.getPath().getLastPathComponent();
					defaultMutableTreeNode.removeAllChildren();
					Object objtreeNodeEntrty = defaultMutableTreeNode.getUserObject();
					if(TreeNodeEntity.class.isInstance(objtreeNodeEntrty)) {
						TreeNodeEntity treeNodeEntrty = (TreeNodeEntity)objtreeNodeEntrty;
						String path = treeNodeEntrty.getPath();
						buildChildNode(new File(path),defaultMutableTreeNode);
						//当本地目录中文件或者文件夹有改变时,树节点重新加载后需调用此方法刷新树节点,否则树节点还是显示的未改变之前的
						//jTree.updateUI();直接调用会出现空指针问题
		                //解决办法:不能直接调用updateUI方法,需要放到SwingUtilities.invokeLater中执行;
		                SwingUtilities.invokeLater(new Runnable() {
		                    public void run() {
		                    	fileBrowserTree.updateUI();
		                    }
		                });
					}
				}
				//节点将要关闭时触发
				@Override
				public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
				}
			});
			
	      	jFrame.add(jScrollPane);
			jFrame.setSize(300, 600);
			jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			jFrame.setLocationRelativeTo(null);
			jFrame.setVisible(true);
	}
	/**
	 * 创建系统根节点
	 * @param rootFile
	 * @return
	 */
    public static DefaultMutableTreeNode buildrootNode(File[] rootFile) {
    	DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("系统资源");
        for (File subFile : rootFile) {
        	TreeNodeEntity treeNodeEntity = new TreeNodeEntity();
        	treeNodeEntity.setName(subFile.getPath());
        	treeNodeEntity.setPath(subFile.getPath());
        	DefaultMutableTreeNode dirNode = new DefaultMutableTreeNode(treeNodeEntity);
        	if (!subFile.isDirectory()) {
        		dirNode.setAllowsChildren(false);
        	}
            rootNode.add(dirNode);
        }
        return rootNode;
    }
    
    /**
     * 展开节点时创建所展开节点的子节点(加载文件夹和图片类型)
     * @param rootFile
     * @param rootNode
     */
    public static void buildChildNode(File rootFile,DefaultMutableTreeNode rootNode) {
        File[] subFiles = rootFile.listFiles();
        for (File subFile : subFiles) {
        	if(subFile!=null) {
        		TreeNodeEntity treeNodeEntity = new TreeNodeEntity();
            	treeNodeEntity.setName(subFile.getName());
            	treeNodeEntity.setPath( subFile.getPath());
            	DefaultMutableTreeNode subNode = new DefaultMutableTreeNode(treeNodeEntity);
            	//只加载允许的文件类型
                if (!subFile.isDirectory()) {
                	//将不是文件夹的节点标记为叶子节点
                	subNode.setAllowsChildren(false);
                	rootNode.add(subNode);
            	}else if(subFile.isDirectory()){
            		rootNode.add(subNode);
            	}
        	}
        }
    }
	
}
class TreeNodeEntity {
	private String name;
	private String path;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	
	// 重点在toString,节点的显示文本就是toString,否则会显示该对象的地址
	public String toString(){
		return name;
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值