将Eclipse插件转换为RCP应用程序(上)

有不少朋友问到如何把一个已有的Eclipse插件转换为RCP应用程序,其实这个 过程并不复杂,因为RCP应用也是基于插件的结构,可以说RCP 就是精简后的 Eclipse平台,只是我们要对这个平台做一些定制工作。将任何一个传统的 Eclipse插件项目转换到RCP可以分为两个步骤,这篇先介绍第一个步骤:建立应 用程序。

在GEF入门系列(三、应用实例)里我曾做过一个精简的GEF应用程序(下载) ,这一篇里我就一步一步的把这个例子转换为RCP应用程序(点击下载转换后的项 目打包)。应用程序(Application)是通过扩展 org.eclipse.core.runtime.applications扩展点建立的,其作用是让Eclipse知 道你的RCP需要什么样的功能,比如界面上有哪些视图,菜单和工具条,应用程序 窗口的初始大小等等。在plugin.xml里添加应用程序的定义很简单,像下面这样 指定一个id和一个类名就可以了。

接下来我们的主要任务是实现这个类,MyApplication必须实现 org.eclipse.core.runtime.IPlatformRunnable接口,这个接口只定义了一个 run()方法,对于Eclipse Platform来说这个方法就相当于传统java程序的main() 方法,是入口方法。所有RCP应用程序里这个方法的实现几乎是完全一样的,即启 动 Workbench,并把一个WorkbenchAdvisor实例作为参数传给它,如下所示:

public class MyApplication implements IPlatformRunnable {public Object run(Object args) throws Exception {Display display = PlatformUI.createDisplay();try {int returnCode = PlatformUI.createAndRunWorkbench(display, new MyWorkbenchAdvisor());if (returnCode == PlatformUI.RETURN_RESTART) {return IPlatformRunnable.EXIT_RESTART;}return IPlatformRunnable.EXIT_OK;} finally {display.dispose();}}}

所以应用程序的定制实际上是通过这个WorkbenchAdvisor实例实现的。现在我 们要构造 org.eclipse.ui.application.WorkbenchAdvisor类的一个子类,也就 是上面代码里出现的 MyWorkbenchAdvisor,然后覆盖它的一些方法。比较重要的 是这两个方法:createWorkbenchWindowAdvisor() 返回一个 WorkbenchWindowAdvisor实例,从类名不难看出它的作用是定制应用程序窗口, 包括菜单和工具条,稍后将详细介绍; getInitialWindowPerspectiveId()返回 一个透视图的id字符串,这个透视图定义RCP应用程序的界面布局,所以如果在原 来的插件里你没有定义透视图,现在必须要新定义一个了。

public class MyWorkbenchAdvisor extends WorkbenchAdvisor {private static final String PERSPECTIVE_ID = "com.example.ui.MyPerspective";public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {return new MyWorkbenchWindowAdvisor(configurer);}public String getInitialWindowPerspectiveId() {return PERSPECTIVE_ID;}public void initialize(IWorkbenchConfigurer configurer) {super.initialize(configurer);//The workaround callWorkbenchAdapterBuilder.registerAdapters();} }

注意:因为我们这个RCP里用到了Resource视图,而这个视图依赖 org.eclipse.ui.ide,所以要在上面的 initialize()方法里手动注册一下 Adapter,否则Resource视图里无法显示现有项目。(Resource视图在RCP里不推 荐使用,这个调用是无奈之举,请参考这条bug报告)

现在来看一下前面代码里MyWorkbenchWindowAdvisor是怎样实现的,它继承自 org.eclipse.ui.application.WorkbenchWindowAdvisor类,为了定义窗口大小和 标题要覆盖 preWindowOpen()方法,可以看到我们还顺便隐藏了工具条;要定义 窗口的菜单和工具条,应该覆盖 createActionBarAdvisor()方法,返回的 ActionBarAdvisor实例马上会介绍到。

public class MyWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {public MyWorkbenchWindowAdvisor (IWorkbenchWindowConfigurer configurer) {super (configurer);}public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) {return new MyActionBarAdvisor(configurer);}public void preWindowOpen() {IWorkbenchWindowConfigurer configurer = getWindowConfigurer();configurer.setInitialSize(new Point(700, 500));configurer.setShowCoolBar(false);configurer.setShowStatusLine(false);configurer.setTitle ("My RCP Application");}}

有没有注意到,我们新建(和即将新建)的几个类有这样的引用关系: MyApplication->MyWorkbenchAdvisor- >MyWorkbenchWindowAdvisor- >MyActionbarAdvisor,在3.1M5以前的Eclipse RCP版本中,还没有 ActionbarAdvisor这个类,大部分应用程序定制工作都是在 WorkbenchWindowAdvisor这一个类中做的,带来的问题是这个类的代码很长,可 复用的程度比较低;采用现在这种方式就方便多了,比如可以定义几个 ActionbarAdvisor然后在 WorkbenchWindowAdvisor中根据需要做出选择,得到的 应用程序就具有不同的功能,等等。

现在就来看看MyActionbarAdvisor是怎么实现的,它继承 org.eclipse.ui.application.ActionBarAdvisor类,我们先在makeActions()里 构造需要出现在菜单或工具条上的命令,注意要调用register()方法注册这些命 令,作用是在应用程序结束后释放资源,同时支持快捷键操作;然后在 fillMenuBar()方法里把这些命令加入主菜单,因为我们隐藏了工具条,所以没有 覆盖fillCoolBar()方法,另外你还可以通过覆盖 fillStatusLine()定义自己的 状态栏。我们的这个类实现得很简单,只是一个退出程序菜单项,你应该根据需 要添加自己的命令。

public class MyActionBarAdvisor extends ActionBarAdvisor {private IWorkbenchAction exitAction;public MyActionBarAdvisor (IActionBarConfigurer configurer) {super(configurer);}protected void makeActions(final IWorkbenchWindow window) {exitAction = ActionFacTory.QUIT.create(window);register(exitAction);}protected void fillMenuBar (IMenuManager menuBar) {MenuManager fileMenu = new MenuManager("&File",IWorkbenchActionConstants.M_FILE);menuBar.add (fileMenu);fileMenu.add(exitAction);}}

现在,应用程序需要的类都写好了,让我们检查一下应用程序是否可以正常启 动。在Eclipse主菜单上选择Run->Debug…命令,在对话框左边的“Eclipse Application”组下新建一个运行项“gefpractice-rcp”,在“Program to Run ”组下选择“Run an application”,然后在下拉列表里找到我们的应用程序id ,要说明的是在applications扩展点里我们指定的id是 “myapplication”,而 这里列出的id则添加了插件id作为前缀,变成了“GefPractice- RCP.myapplication”,如图1所示。

因为缺省运行会启动Eclipse的全部插件,这样在应用程序里会出现多余的菜 单项和功能,所以要设置为只启动我们的这一个插件,方法是切换到 Plug-ins属 性页,选择“Choose plug-ins and fragments to launch from the list”,点 击右边的“Deselect All”按钮清空选择列表,勾选上我们的插件项目,再按 “Add Required Plug-ins”让Eclipse自动添加它依赖的其他插件就可以了,如 图2所示。

现自使用这个运行配置启动我们的应用程序,会得到一个很“干净”的界面, 如图3所示,如果不是那些Eclipse特有的编辑器/视图的标题栏,你能猜出它是一 个Eclipse应用程序吗?作为对比,这是Eclipse插件的版本的运行截图。

建立了应用程序,代码的部分就算是完成了,但要得到一个完整的可独立运行 的产品这样还不够,下一个帖子里将介绍另一个步骤:将应用程序包装为产品。 如果等不及可以先看Branding Your Application这篇文章,只是这篇文章写得比 较早,我下个部分要写的是使用.product配置产品,可以更方便的达到相同的目 的。关于建立应用程序的更多内容请参考Rich Client TuTorial,这个教程共有 三个部分,我当时就是通过它学习的,后来它按照RCP API的发展又及时更新了内 容,是难得的入门材料。

本文配套源码

志在山顶的人,不会贪念山腰的风景。

将Eclipse插件转换为RCP应用程序(上)

相关文章:

你感兴趣的文章:

标签云: