树的复选框用CheckboxTreeViewer实现.由于其子类ContainerCheckedTreeViewer在没有选择全部子节点时可以自动将父节点设置成灰选,所以实现树的复选框更多的是用ContainerCheckedTreeViewer.
关于这个ContainerCheckedTreeViewer类我没有在SWT/JFace的API文档中找到,但是在Eclipse中查看源码能找到.
CheckboxTreeViewer的继承类关系图:
TreeView4.java
1 public class TreeViewer4 { 2 public static void main(String[] args) { 3 new TreeViewer4().open(); 4 } 5 6 public void open() { 7 final Display display = new Display(); 8 final Shell shell = new Shell(); 9 shell.setSize(300, 300); 10 // -----------界面核心代码------------------- 11 shell.setLayout(new FillLayout()); 12 // 用ContainerCheckedTreeViewer完全替换TreeViewer 13 ContainerCheckedTreeViewer tv = new ContainerCheckedTreeViewer(shell, SWT.BORDER); 14 tv.setUseHashlookup(true); // 加快查找速度 15 16 Tree tree = tv.getTree(); 17 tree.setHeaderVisible(true); 18 TreeColumn column = new TreeColumn(tree, SWT.LEFT); 19 column.setText("名称"); 20 column.setWidth(150); 21 column = new TreeColumn(tree, SWT.LEFT); 22 column.setText("子结点数"); 23 column.setWidth(80); 24 column = new TreeColumn(tree, SWT.LEFT); 25 column.setText("性别"); 26 column.setWidth(40); 27 28 tv.setContentProvider(new TreeViewerContentProvider());//设置"内容器" 29 tv.setLabelProvider(new MyTableLableProvider());//设置"标签器" 30 // 和TableViewer一样,数据的入口也是setInput方法 31 List<Country> input = (List)DataFactory.createTreeData(); 32 tv.setInput(input); 33 MyActionGroup2 actionGroup = new MyActionGroup2(tv);// 改用另一个ActionGroup 34 actionGroup.fillContextMenu(new MenuManager());// 将按钮注入到菜单对象中 35 // -----------END------------------ 36 shell.open(); 37 while (!shell.isDisposed()) { 38 if (!display.readAndDispatch()) 39 display.sleep(); 40 } 41 display.dispose(); 42 } 43 }
MyActionGroup2.java
1 public class MyActionGroup2 extends ActionGroup { 2 private ContainerCheckedTreeViewer tv; 3 4 public MyActionGroup2(ContainerCheckedTreeViewer tv) { 5 this.tv = tv; 6 } 7 //这个地方直译方法名就是"填充上下文菜单fillContextMenu()传入的是一个菜单管理器的类(接口)" 8 public void fillContextMenu(IMenuManager mgr) { 9 MenuManager menuManager = (MenuManager) mgr; 10 menuManager.add(new SelectAllAction());//通过菜单管理器增加一个"全选"的Action() 11 menuManager.add(new RemoveEntryAction());//通过菜单管理器增加一个"删除"的Action() 12 Tree tree = tv.getTree();//getTree()是TreeViewer类下的一个方法. 就是返回这个视图的树形结构. 13 Menu menu = menuManager.createContextMenu(tree); 14 tree.setMenu(menu); 15 } 16 17 private class SelectAllAction extends Action {//首先继承Action接口 18 public SelectAllAction() {//首先就是重写这个Action对应的构造方法 19 setText("勾选当前结点的所有子结点"); 20 } 21 22 public void run() {//每个Action中都有对应的run()方法. 23 IStructuredSelection selection = (IStructuredSelection) tv.getSelection(); 24 ITreeEntry entry = (ITreeEntry) (selection.getFirstElement()); 25 tv.setSubtreeChecked(entry, true); // false不勾选 26 } 27 } 28 29 // 删除结点的Action类 30 private class RemoveEntryAction extends Action { 31 public RemoveEntryAction() { 32 setText("删除"); 33 } 34 35 public void run() { 36 Object[] checks = tv.getCheckedElements();// 取得被勾选的结点(包括灰选) 37 if (checks.length == 0) { 38 MessageDialog.openInformation(null, "提示", "请先勾选记录"); 39 return; 40 } 41 List<ITreeEntry> inputList = (List<ITreeEntry>) tv.getInput(); 42 for (Object object : checks) { 43 if (tv.getGrayed(object)) 44 continue;// 灰选结点不删除 45 ITreeEntry entry = (ITreeEntry) object; 46 remove(inputList, entry); 47 tv.remove(entry); 48 } 49 } 50 51 private void remove(List<ITreeEntry> list, ITreeEntry entry) { 52 if (list == null) 53 return; 54 for (Iterator it = list.iterator(); it.hasNext();) { 55 ITreeEntry o = (ITreeEntry) it.next(); 56 if (o.getName().equals(entry.getName())) { 57 it.remove(); 58 return; 59 } else { 60 remove(o.getChildren(), entry); 61 } 62 } 63 } 64 } 65 }
本文转自SummerChill博客园博客,原文链接:http://www.cnblogs.com/DreamDrive/p/4178243.html,如需转载请自行联系原作者