14.4 给表格加上右键菜单(Action类、ActionGroup类、MenuManager类)
本节来给表格加上如图14.6所示的右键菜单。本节实例在前两节的代码基础上修改完成(完整代码见配书光盘的TableViewer3.java文件)。

图14.6 右键菜单的效果图
14.4.1 Action、ActionGroup、MenuManager介绍
SWT中菜单是Menu类,本书在前面章节中已经介绍过Menu类的使用,在第11章中菜单项用MenuItem类来实现。但在实际项目中,同一种功能会有多种表现形式,例如Eclipse中的“新建”功能,它会分别出现在主菜单、主工具栏、右键菜单里。如果都是用MenuItem来实现,就需要写3份类似的代码,以后也要维护3份代码。当然也可以将事件处理写成外部类来共享代码,但名称、图像以及一些其他的信息写成外部类来共享则不太方便。
JFace包中已经对以上问题提供了解决方案,JFace提供了一个Action类,它将名称、图像、动作处理程序等集成在其中,这样就可以共享这些Action来形成菜单项、工具栏按钮等。
当然在底层最后用于Menu的还是MenuItem对象,将Action转化成MenuItem是由MenuManager(菜单管理器)来完成的。MenuManager简化了菜单的创建,一旦生成了MenuManager对象,就可以通用于菜单栏、弹出菜单、工具栏下拉菜单。
另外,Action写成一个个的类会很零乱,JFace又提供了一个ActionGroup类用于统一管理Action,然后让外界程序通过ActionGroup来访问Action。当然,并非一定要使用ActionGroup类来管理Action,只是用它会更好。
14.4.2 创建Action和ActionGroup
以下代码演示了如何创建Action、ActionGroup,以及如何使用MenuManager。
//--------文件名:MyActionGroup.java----------
public class MyActionGroup extends ActionGroup {
private TableViewer tv;
// 在Action要使用到TableViewer对象,所以通过构造函数把它传进来
public MyActionGroup(TableViewer tv) {
this.tv = tv;
}
// 生成菜单Menu,并将两个Action传入
public void fillContextMenu(IMenuManager mgr) {
// 加入两个Action对象到菜单管理器
MenuManager menuManager = (MenuManager) mgr;
menuManager.add(new OpenAction());
menuManager.add(new RefreshAction());
// 生成Menu并挂在表格table上。menu和table两个对象互为对方的参数
Table table = tv.getTable();
Menu menu = menuManager.createContextMenu(table);
table.setMenu(menu);
}
// “打开”的Action类
private class OpenAction extends Action {
public OpenAction() { setText("打开"); }
public void run() {// 继承自Action的方法,动作代码写在此方法中
IStructuredSelection selection = (IStructuredSelection) tv.getSelection();
PeopleEntity o = (PeopleEntity) selection.getFirstElement();
if (o == null)
MessageDialog.openInformation(null, null, "请先选择记录");
else
MessageDialog.openInformation(null, null, o.getName());
}
}
// “刷新”的Action类
private class RefreshAction extends Action {
public RefreshAction() { setText("刷新"); }
public void run() {
tv.refresh(); //表格的刷新方法,界面会重新读取数据并显示
}
}
}
14.4.3 在主程序中使用ActionGroup、MenuManager
MyActionGroup类封装了Action以及Action和菜单Menu之间的交互代码。最后,只需将以下代码加入到shell.open()语句之前即可。
//生成一个ActionGroup对象,并调用fillContextMenu方法将按钮注入到菜单对象中
MyActionGroup actionGroup = new MyActionGroup(tv);
actionGroup.fillContextMenu(new MenuManager());
程序说明:图14.7说明了在程序中是如何创建右键菜单的,在主程序生成一个MenuManager对象传给ActionGroup对象,然后再通过ActionGroup内部的createContextMenu方法生成一个菜单对象Menu,最后用Menu的add()方法将Action加入。

图14.7 程序分析图






