Tree Check 带复选框的树

 

在SWT/JFace中,带复选框树最好使用ContainerCheckedTreeViewer(或者CheckedTreeViewer)来实现,今天遇到直接使用tree来实现的。

简单备记:

import java.awt.image.BufferedImage;
import java.io.File;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.filechooser.FileSystemView;
import javax.swing.plaf.IconUIResource;

import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.internal.UIPlugin;
/**
 * <p>
 * Title: MultiDirectoryDialog.java
 * </p>
 * <p>
 * Description: 文件选择框,支持多选
 * </p>
 * 
  */
public class MultiDirectoryDialog extends Dialog {

	// 菜单提示
	private String message = "";
	private Shell parent;
	// 列表树
	private Tree tree;
	// 用来获取系统文件的相关信息
	private FileSystemView fsv;

	// 用来存放选择的文件夹,用分号隔开
	private StringBuilder resultFile = new StringBuilder("");

	/**
	 * 构造方法
	 * 
	 * @param parent
	 *            父类
	 */
	public MultiDirectoryDialog(Shell parent) {
		super(parent);
		this.parent = parent;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets
	 * .Composite)
	 */
	protected Control createDialogArea(Composite parent) {

		parent.setDragDetect(false);
		Composite container = (Composite) super.createDialogArea(parent);
		container.setLayout(new FormLayout());

		final Label showTipLabel = new Label(container, SWT.NONE | SWT.MULTI);
		showTipLabel.setText(message);
		final FormData fd_showTipLabel = new FormData();
		fd_showTipLabel.top = new FormAttachment(0, 15);
		fd_showTipLabel.bottom = new FormAttachment(0, 32);
		fd_showTipLabel.right = new FormAttachment(0, 170);
		fd_showTipLabel.left = new FormAttachment(0, 30);
		showTipLabel.setLayoutData(fd_showTipLabel);

		final Composite treeComposite = new Composite(container, SWT.BORDER);
		treeComposite.setDragDetect(false);
		treeComposite.setLayout(new FormLayout());
		// treeComposite.set
		// scrolledComposite.setAlwaysShowScrollBars(true);
		final FormData fd_scrolledComposite = new FormData();
		fd_scrolledComposite.right = new FormAttachment(100, 0);
		fd_scrolledComposite.left = new FormAttachment(0, 0);
		fd_scrolledComposite.bottom = new FormAttachment(100, 0);
		fd_scrolledComposite.top = new FormAttachment(0, 50);
		treeComposite.setLayoutData(fd_scrolledComposite);
		// 新建树
		tree = new Tree(treeComposite, SWT.DEFAULT);
		final FormData fd_tree = new FormData();
		fd_tree.left = new FormAttachment(0, 5);
		fd_tree.bottom = new FormAttachment(0, 300);
		fd_tree.top = new FormAttachment(0, 0);
		fd_tree.right = new FormAttachment(0, 400);
		tree.setLayoutData(fd_tree);
		treeComposite.setData(tree);

		// 为树增加单击方法
		tree.addListener(SWT.Expand, new Listener() {
			public void handleEvent(final Event event) {
				final TreeItem item = (TreeItem) event.item;
				TreeItem[] items = item.getItems();
				for (int i = 0; i < items.length; i++) {
					if (items[i].getData() != null)
						return;
					items[i].dispose();
				}

				// 初始化该文件下的节点
				File file = (File) item.getData();
				File[] childFile = file.listFiles();
				for (File sfile : childFile) {
					if (sfile.isDirectory()) {
						initFile(item, sfile);
					}
				}

			}

		});

		// 获取系统文件信息
		fsv = FileSystemView.getFileSystemView();
		File[] file = fsv.getRoots();

		TreeItem item = new TreeItem(this.tree, SWT.NONE);
		String fileName = file[0].getName();
		item.setText(fileName);
		item.setData(file[0]);
		Image img = getIcon(file[0]);
		if (img != null)
			item.setImage(img);
		// new TreeItem(item, 0);
		listFile(item, file[0], 1);
		return container;
	}

	/**
	 * 本类用来初始化文件夹下的文件夹
	 * 
	 * @param treeitem
	 *            父节点
	 * @param file
	 *            要初始化的文件夹
	 * @param flag
	 *            0:由外部调用,其它:递归调用
	 */
	private void listFile(TreeItem treeitem, File file, int flag) {
		File[] childFile = file.listFiles();
		if (flag == 0) {// 如果是外部调用,则再初始一级,以用来显示图标前的十一号。
			for (File sfile : childFile) {
				if (sfile.isDirectory()) {
					// 初始化item的相关数据
					TreeItem item = initFile(treeitem, sfile);
					// 初始化下一级item
					listFile(item, sfile, 1);// 只多这一行
				}
			}

		} else {// 如果是自身调用,则说明已经为第二级文件夹,不需要再初始化下一级
			for (File sfile : childFile) {
				if (sfile.isDirectory()) {
					initFile(treeitem, sfile);
				}
			}
		}
	}

	/**
	 * 初始化item的相关数据
	 * 
	 * @param treeitem
	 *            要初始化item的父item
	 * @param file
	 *            初始化item对应的file
	 * @return 初始化后的item
	 */
	private TreeItem initFile(TreeItem treeitem, File file) {

		TreeItem item = new TreeItem(treeitem, SWT.NONE);
		item.setText(fsv.getSystemDisplayName(file));

		item.setData(file);
		Image img = getIcon(file);
		if (img != null)
			item.setImage(img);
		// 如果还是文件夹,则加一个空节点,以使十号显示出来
		if (file.isDirectory())
			new TreeItem(item, 0);
		return item;
	}

	/**
	 * 获取文件图标
	 * 
	 * @param file
	 *            要获取图标的文件
	 * @return 图标
	 */
	public Image getIcon(File file) {
		ImageData imageData = null;
		// 取得awt的icon对像并转化为swt的image对像
		Icon icon = fsv.getSystemIcon(file);
		if (icon instanceof IconUIResource) {
		} else {
			// BufferedImage bi = ImageConvertor.getBufferedImage((ImageIcon)
			// icon);
			// imageData = ImageConvertor.getImageData(bi);
			// imageData = new Image(Display.getDefault(),50,50).getImageData();
		}
		Image img = null;

		if (imageData != null)
			img = new Image(parent.getDisplay(), imageData);

		return img;
	}

	/**
	 * Create contents of the button bar
	 * 
	 * @param parent
	 */
	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		createButton(parent, IDialogConstants.OK_ID, "确定", true);
		createButton(parent, IDialogConstants.CANCEL_ID, "取消", false);
	}

	/**
	  SWT.MULTI创建出可以让用户作出多重选取的tree。SWT.CHECK样式的Tree会产生checkbox的Tree。如果使用了SWT.CHECK的样式,就需要判断哪些项目被选取了。通过调用TreeItem的getChecked()来判断某个项目是否被checked。下面的程序在循环中判断每个TreeItem的状态:
		TreeItem[] tia=t.getItems();
		  for(int i=0;i<tia.length;i++){
		   if(tia[i].getChecked()){
		    System.out.print("Checked");
		   }
		  TreeItem []child=tia[i].getItems();
		  for(int n=0;n<child.length;n++)
		   if(child[n].getChecked())
		    System.out.print("Checked");
		    }
		
		以上的代码只能用在仅有一层子项目的tree上。多层的tree需要循环运算来处理。
		
		SWT.CHECK样式的Tree对象在你需要让用户对Tree作出多重选取但又不想要SWT.MULTI模式的额外成本的时候是合适的(但若是要使用选取出的TreeItem来采取某些像是产生list内容这样的动作时则不适用)
	 */
	protected void buttonPressed(int buttonId) {
		if (buttonId == IDialogConstants.OK_ID) {

			TreeItem[] treeitem = tree.getItems();
			for (int i = 0; i < treeitem.length; i++) {
				if (treeitem[i].getChecked()) {
					if (treeitem[i].getChecked()) {
						File file = (File) treeitem[i].getData();
						resultFile.append(file.getPath()).append(";");
					}
				}
				TreeItem[] child = treeitem[i].getItems();
				for (int n = 0; n < child.length; n++)
					if (child[n].getChecked()) {
						File file = (File) child[n].getData();
						resultFile.append(file.getPath()).append(";");
					}
			}
			System.out.println(resultFile.toString());
		}
		super.buttonPressed(buttonId);
	}

	/**
	 * 设置 message
	 * 
	 * @return
	 */
	public String getMessage() {
		return message;
	}

	/**
	 * 获取message
	 * 
	 * @param message
	 */
	public void setMessage(String message) {
		this.message = message;
	}

	/**
	 * @return
	 */
	public StringBuilder getResultFile() {
		return resultFile;
	}

	/**
	 * @param resultFile
	 */
	public void setResultFile(StringBuilder resultFile) {
		this.resultFile = resultFile;
	}

	public static void main(String[] args) {
		final Display display = Display.getDefault();
		final Shell shell = new Shell(display, SWT.ON_TOP | SWT.CLOSE);
		shell.setSize(327, 253);
		Dialog dialog = new MultiDirectoryDialog(shell);
		if (dialog.open() == IDialogConstants.OK_ID) {// 是否单击“确定”按钮
			System.out.println("helo");
		}

		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();

	}
}

你可能感兴趣的:(eclipse,UI,swing)