SWT虚拟树

在用SWT进行桌面开发的过程中需要经常使用到Tree组件,往往数据量大的时候创建Tree非常耗时间,直接导致界面假死,这时候虚拟树就起到关键作用了。

以下是一个解析JAR文件构建Tree的例子:

测试使用的是jdk下的tool.jar文件,该文件比较大,内部包含文件也比较多,用普通的Tree构建肯定是死慢的。

 

package test;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

/**
 * 测试虚拟树
 * @author  xoHome
 */
public class LoadJarTest {

	public static void main(String[] args) {
		try {
			//new LoadJarTest().test();
			new LoadJarTest().test2();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 树目录结构
	 */
	class Entry {
		
		List<String> file = new ArrayList<String>();
		
		Map<String, Entry> dire = new LinkedHashMap<String, Entry>();
		
		void put(String url, boolean isDir) {
			String[] us = url.split("/");
			// 找出最根目录
			int s = 0, e = isDir ? us.length : us.length - 1;
			Entry entry = this;
			for (; s < e; s++) {
				Entry ey = entry.dire.get(us[s]);
				if (ey == null) {
					ey = new Entry();
					entry.dire.put(us[s], ey);
				}
				entry = ey;
			}
			if (!isDir) {
				entry.file.add(us[us.length - 1]);
			}
		}
		
		Map.Entry<String, Entry> getDirEntry(int index) {
			return (Map.Entry<String, Entry>) dire.entrySet().toArray()[index];
		}
	}
	
	public Entry createTree(String url) throws IOException {
		JarFile jar = new JarFile(new File(url));
		Enumeration<JarEntry> enumeration = jar.entries();
		Entry entry = new Entry();
		for (JarEntry jentry; enumeration.hasMoreElements();) {
			jentry = enumeration.nextElement();
			entry.put(jentry.getName(), jentry.isDirectory());
		}
		// 打印测试
		//print(entry, 0);
		return entry;
	}
	
	public void test2() {
		final Display display = Display.getDefault();
		final Shell shell = new Shell(display);
		shell.setBounds(500, 150, 450, 500);
		
		final Tree tree = new Tree(shell, SWT.VIRTUAL | SWT.BORDER | SWT.SCROLL_LINE);
		tree.setBounds(0, 0, 350, 500);
		tree.addListener(SWT.SetData, new Listener() {
			@Override
			public void handleEvent(Event event) {
				TreeItem item = (TreeItem) event.item;
				TreeItem parentItem = item.getParentItem();
				int index = event.index;
				Entry entry = (Entry) (parentItem == null ? tree.getData() : parentItem.getData());
				boolean isDir = entry.dire.size() > index;
				if (isDir) {
					Map.Entry<String, Entry> dirEntry = entry.getDirEntry(index);
					StringBuilder pack = new StringBuilder(dirEntry.getKey());
					Entry next = dirEntry.getValue();
					while (true) {
						if(next.dire.size() == 1 && next.file.size() == 0){
							dirEntry = next.getDirEntry(0);
							pack.append(".").append(dirEntry.getKey());
							next = dirEntry.getValue();
							continue;
						}
						break;
					}
					item.setText(pack.toString());
					item.setData(next);
					item.setItemCount(next.dire.size() + next.file.size());
				} else {
					item.setText(entry.file.get(index - entry.dire.size()));
				}
			}
		});
		
		Button btn = new Button(shell, SWT.NONE);
		btn.setBounds(355, 10, 70, 25);
		btn.setText("选择JAR");
		btn.addListener(SWT.Selection, new Listener() {
			@Override
			public void handleEvent(Event arg0) {
				FileDialog dialog = new FileDialog(shell);
				dialog.setText("选择Jar文件");
				dialog.setFilterExtensions(new String[] { "*.jar" });
				String path = dialog.open();
				if (path == null) {
					return;
				}
				Entry entry = null;
				try {
					entry = createTree(path);
				} catch (IOException e) {
					e.printStackTrace();
					return;
				}
				tree.clearAll(true);
				tree.setData(entry);
				tree.setItemCount(entry.dire.size() + entry.file.size());
			}
		});
		
		shell.open();
		while (!shell.isDisposed()) {
			if(!display.readAndDispatch()){
				display.sleep();
			}
		}
		display.dispose();
	}
	
	/**
	 * 打印测试
	 * @param entry
	 * @param margin
	 */
	public void print(Entry entry, int margin) {
		StringBuffer space = new StringBuffer();
		for (int i = 0; i < margin; i++) {
			space.append("\t");
		}
		if (entry.dire.size() > 0) {
			Set<Map.Entry<String, Entry>> sets = entry.dire.entrySet();
			for (Map.Entry<String, Entry> es : sets) {
				System.out.println(space.toString() + es.getKey());
				Entry next = es.getValue();
				if (next != null) {
					print(next, margin + 1);
				}
			}
		}
		if (entry.file.size() > 0) {
			for (String f : entry.file) {
				System.out.println(space.toString() + f);
			}
		}
	}
	
}

附一个预览截图:

转载于:https://my.oschina.net/5zx1Vm/blog/56115

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值