1.先来看看项目截图:
2.本项目是maven写的,下面是maven配置:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.pan</groupId>
<artifactId>myui</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<swt.version>4.3</swt.version>
<jface.version>3.3.0-I20070606-0010</jface.version>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>jface</artifactId>
<version>${jface.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.swt.org.eclipse.swt.win32.win32.x86_64.4.3.swt</groupId>
<artifactId>org.eclipse.swt.win32.win32.x86_64</artifactId>
<version>${swt.version}</version>
</dependency>
</dependencies>
</project>
3.界面代码TreeDialog.java 如下:
package org.pan.tree.ui; import java.util.Arrays; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.swt.widgets.Widget; import org.pan.tree.domain.City; import org.pan.tree.domain.ITreeNode; public class TreeDialog { protected Shell shell; private CheckboxTreeViewer treeViewer; private Tree tree; /** * Launch the application. * * @param args */ public static void main(String[] args) { try { TreeDialog window = new TreeDialog(); window.open(); } catch (Exception e) { e.printStackTrace(); } } /** * Open the window. */ public void open() { Display display = Display.getDefault(); createContents(); shell.open(); shell.layout(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } } /** * Create contents of the window. */ protected void createContents() { shell = new Shell(); shell.setSize(450, 300); shell.setText("SWT Application"); shell.setLayout(new FillLayout()); SashForm sashForm = new SashForm(shell, SWT.NONE); Composite composite = new Composite(sashForm, SWT.NONE); composite.setLayout(new FillLayout()); treeViewer = new CheckboxTreeViewer(composite, SWT.BORDER|SWT.CHECK); treeViewer.setLabelProvider(new TreeLabelProvider()); treeViewer.setContentProvider(new TreeContentProvider()); tree = treeViewer.getTree(); initTree(); Composite composite_1 = new Composite(sashForm, SWT.NONE); sashForm.setWeights(new int[] { 2, 3 }); treeViewer.addCheckStateListener(new ICheckStateListener() { public void checkStateChanged(CheckStateChangedEvent arg0) { CheckboxTreeViewer checkboxTreeViewer = (CheckboxTreeViewer)arg0.getSource(); boolean checked = arg0.getChecked(); checkboxTreeViewer.setSubtreeChecked(arg0.getElement(), checked); TreeItem ti = (TreeItem)checkboxTreeViewer.testFindItem(arg0.getElement()); tree.setSelection(ti); TreeItem parent = ti.getParentItem(); if(parent == null){ return; } TreeItem[] items = parent.getItems(); int checkItems = 0; for (TreeItem treeItem : items) { if(treeItem.getChecked() && !treeItem.getGrayed()){ checkItems = checkItems + 1; } } ti.setChecked(checked); if(checkItems == 0){ parent.setChecked(false); return; } if(checkItems == items.length){ parent.setGrayed(false); parent.setChecked(true); return; } if(checkItems != items.length){ parent.setChecked(true); parent.setGrayed(true); return; } } }); } public void initTree() { City city = new City("大中国"); City city2 = new City("湖北"); city.getChildren().add(city2); City city3 = new City("咸宁"); city2.getChildren().add(city3); City city4 = new City("武汉"); city2.getChildren().add(city4); City city5 = new City("湖南"); city.getChildren().add(city5); treeViewer.setInput(Arrays.asList(city)); } }
4.treeviewer中用到的provider:
TreeLabelProvider.java:
package org.pan.tree.ui; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.swt.graphics.Image; import org.pan.tree.domain.ITreeNode; public class TreeLabelProvider extends LabelProvider implements ILabelProvider { public String getText(Object element) { ITreeNode node = (ITreeNode) element; return node.getName(); } public Image getImage(Object element) { return null; } }
TreeContentProvider.java
package org.pan.tree.ui; import java.util.List; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.Viewer; import org.pan.tree.domain.ITreeNode; public class TreeContentProvider implements ITreeContentProvider { public Object[] getElements(Object inputElement) { if (inputElement instanceof List) { List input = (List) inputElement; return input.toArray(); } return new Object[0]; } public Object[] getChildren(Object parentElement) { ITreeNode node = (ITreeNode) parentElement; List list = node.getChildren(); if (list == null) { return new Object[0]; } return list.toArray(); } public boolean hasChildren(Object element) { ITreeNode node = (ITreeNode) element; List list = node.getChildren(); return !(list == null || list.isEmpty()); } // 以下三个函数根据需要填充 public Object getParent(Object element) { return null; } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } public void dispose() { } }
5.填充对象为树结构,所以为树结构写了一下通用的接口,所有树型数据都必须实现这个接口:
ITreeNode.java:
package org.pan.tree.domain; import java.util.List; public interface ITreeNode { public String getName(); public String setName(String name); public boolean getChecked(); public void setChecked(boolean checked); public List getChildren(); public void setChildren(List list); }
以城市结构作为类子:
City.java:
package org.pan.tree.domain; import java.util.ArrayList; import java.util.List; public class City implements ITreeNode { private String name; private boolean checked; private List<City> children = new ArrayList<City>(); public City() { } public City(String name) { this.name = name; } public String getName() { return this.name; } public String setName(String name) { return this.name = name; } public boolean getChecked() { return checked; } public void setChecked(boolean checked) { this.checked = checked; } public List<City> getChildren() { return this.children; } public void setChildren(List list) { this.children.clear(); this.children.addAll(children); } @Override public String toString() { return "City [name=" + name + "]"; } }
下面是最终的效果图:
为在达下图中的选中效果,折腾了很久,在监听勾选的事件中,看似其中有一些比较重复的代码,但的确是缺一不可.因为勾选的项目不一定是我们当前选中的项目,导致子节点与父节点的显示有误 .好了,可以算是比较完美了.