给树加上右键菜单,及实现菜单相应功能

本节实例的效果如图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());
}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值