本节实例的效果如图15.5所示。给TreeViewer加右键菜单的方法和TableViewer相似,也要用到Action、ActionGroup、MenuManager类,当然程序要根据树的特点稍做改动。
![]() |
图15.5 右键菜单效果图 |
(1)在15.3节主程序的tv.setInput(input)之后插入如下两句:
//--------------完整代码见文件:TreeViewer2.java-------------- MyActionGroup actionGroup = new MyActionGroup(tv);// 生成一个ActionGroup对象 actionGroup.fillContextMenu(new MenuManager());// 将按钮注入到菜单对象中 |
(2)创建MyActionGroup类,其代码如下所示。MyActionGroup内含各Action类,在实现Action时,对传入的结点对象要记得进行空值判断,因为TreeViewer的大部分方法都不支持空值参数,会导致异常并中断程序。
public class MyActionGroup extends ActionGroup { private TreeViewer tv; public MyActionGroup(TreeViewer treeViewer) { this.tv = treeViewer; } // 生成菜单Menu,并将两个Action传入 public void fillContextMenu(IMenuManager mgr) { // 加入两个Action对象到菜单管理器 MenuManager menuManager = (MenuManager) mgr; // 类型转换 menuManager.add(new OpenAction()); menuManager.add(new RefreshAction()); menuManager.add(new ExpandAction()); menuManager.add(new CollapseAction()); menuManager.add(new AddEntryAction()); menuManager.add(new RemoveEntryAction()); menuManager.add(new ModifyEntryAction()); // 生成Menu并挂在树Tree上 Tree tree = tv.getTree(); Menu menu = menuManager.createContextMenu(tree); tree.setMenu(menu); } // “打开”的Action类 private class OpenAction extends Action { public OpenAction() { setText("打开"); } public void run() { ITreeEntry entry = getSelTreeEntry(); if (entry != null) MessageDialog.openInformation(null, null, entry.getName()); } } // 刷新的Action类 private class RefreshAction extends Action { public RefreshAction() { setText("刷新"); } // 如果在删除结点时,不同时从数据模型里删除结点。则执行本刷新后,该结点又会从 // 数据模型中取出并显示在界面上 public void run() { tv.refresh(); } } // 展开当前结点的Action类 private class ExpandAction extends Action { public ExpandAction() { setText("展开"); } public void run() { ITreeEntry entry = getSelTreeEntry(); if (entry != null) tv.expandToLevel(entry, 1); // 参数2是展开的层数 } } // 收缩当前结点的Action类 private class CollapseAction extends Action { public CollapseAction() { setText("收缩"); } public void run() { ITreeEntry entry = getSelTreeEntry(); if (entry != null) tv.collapseToLevel(entry, -1); // 参数2是收缩的层数,-1指收缩所有子结点 } } // 给当前结点增加一个子结点的Action类 private class AddEntryAction extends Action { public AddEntryAction() { setText("增加"); } public void run() { ITreeEntry entry = getSelTreeEntry(); if (entry == null || entry instanceof PeopleEntity) return;// 不能给“人”结点增加子结点 InputDialog dialog = new InputDialog(null, "增加子结点", "输入名称:", "a", null); if (dialog.open() == InputDialog.OK) {// 如果单击OK按钮 String entryName = dialog.getValue(); // 得到Dialog输入值 // 根据单击结点的不同类型生成相应的子结点 ITreeEntry newEntry = null; if (entry instanceof CountryEntity) newEntry = new CityEntity(entryName); else if (entry instanceof CityEntity) newEntry = new PeopleEntity(entryName); entry.getChildren().add(newEntry); // 新结点增加到数据模型中 tv.add(entry, newEntry);// newEntry结点增加到entry之下,或用tv.refresh(entry,true)也行 if (!tv.getExpandedState(entry)) // 如果entry是未展开结点则展开它 tv.expandToLevel(entry, 1); } } } // 删除结点的Action类 private class RemoveEntryAction extends Action { public RemoveEntryAction() { setText("删除"); } public void run() { ITreeEntry entry = getSelTreeEntry(); if (entry == null) return; // 从数据模型里删除结点 List list = (List) tv.getInput(); remove(list, entry); // 从界面删除结点,放在从模型删除之后, //否则在删除某个结点的最后一个子结点时会出问题 tv.remove(entry); } private void remove(List list, ITreeEntry entry) { if (list == null)return; for (Iterator it = list.iterator(); it.hasNext();) { ITreeEntry o = (ITreeEntry) it.next(); if (o.getName().equals(entry.getName())) { it.remove(); return; } else { remove(o.getChildren(), entry); } } } } // 修改结点名称的Action类 private class ModifyEntryAction extends Action { public ModifyEntryAction() { setText("修改"); } public void run() { ITreeEntry entry = getSelTreeEntry(); if (entry == null)return; InputDialog dialog = new InputDialog(null, "修改结点", "输入新名称", entry.getName(), null); if (dialog.open() == InputDialog.OK) { String entryName = dialog.getValue(); entry.setName(entryName);//修改数据模型 tv.refresh(entry); // 刷新结点,等效于tv.update(entry,null); } } } // 为共用而自定义的方法:取得当前选择的结点 private ITreeEntry getSelTreeEntry() { IStructuredSelection selection = (IStructuredSelection) tv.getSelection(); return (ITreeEntry) (selection.getFirstElement()); } } |