zhuan zi: http://www.benisoft.com/cn/java/index.htm
Rich Client Platform (RCP)是一种全新的建立Java应用的方式,它完全不逊色于任何为专门平台开发的应用。本教程帮助你快速建立一个RCP应用,并被更新以适用于Eclipse 3.1。
作者 Ed Burnette, SAS
2005年7月更新适用Eclipse 3.1
译者 Cliff Liang
2005年8月
尝试一下:将Eclipse给你那些以前从来没有接触过Eclipse的朋友或同事看,并让他们猜猜看Eclipse是用什么语言写的。他们有可能猜是VB,C++,或C#,因为这些语言被广泛用于开发高质量的客户端应用。当你告诉他们Eclipse是由Java语言开发的时候,看看他们会有什么样的表情, 尤其是他们自己就是Java程序员的话 。
由于Eclipse独特的开放源码许可证,你可以使用Eclipse技术来创建你自己的商业质量的程序。在Eclipse 3.0以前,这也是可能的,但有点困难,尤其是你需要高度定制菜单,布局,和其他用户界面元素的时候。这是因为Eclipse完全是按照IDE的标准设计的。Eclipse 3.0引出了Rich Client Platform(RCP),它基本上重构了Eclipse用户界面的基础部分,使得它可以用于非IDE应用。Eclipse 3.1为RCP提供了新的功能,最重要的是,提供新的支持使工具创建更容易。
如果你想停一下,看看第一部分的代码,你可以在这里下载它们。接下来,我们来看看如何创建一个RCP应用。
RCP应用给予Eclipse plug-in架构,(如果你不熟悉,可以查看参考部分的内容)。因此,你需要为你的主程序建立一个plug-in。Eclipse的plug-in开发环境Plug-in Development Environment(PDE)为开发过程提供了大量的向导对话框和编辑器。选择File > New > Project > Plug-in Development > Plug-in Project,就会显示plug-in项目的向导对话框。在后面的页面中,输入项目名,比如org.eclipse.ui.tutorials.rcp.part1,选择Create a Java project,选择你所针对的Eclipse版本,并选择Create an OSGI bundle manifest for the plug-in。然后点击Next。
如果你使用Eclipse 3.1,你最好选择Create an OSGI bundle manifest for the plug-in。和以前的版本相比,现在这个选项缺省是被选中的。
在向导的下一个页面中,你可以修改plug-in的ID和其他参数。一个重要的问题是,“Would you like to create a rich client application?”。选择Yes。创建一个plug-in所代表的类是可选的,但是对于这个例子,其他选项都可以使用缺省值。选择Next继续。
在Eclipse 3.1中,提供了许多创建RCP应用的模版。这里我们使用最简单的模版。选择Create a plug-in using one of the templates,然后选择Hello RCP模版,这相当于是RCP的“Hello,World”。点击Finish生成项目。Eclipse会打开plug-in的Plug-in Manifest Editor。这个编辑框可以编辑配置来控制你的RCP应用。
如果你看到一个对话框询问你是否切换到Plug-in Development透视图,你可以点击Remember my decision,并选择Yes。
尝试RCP应用在以往是有点乏味的。你必须创建一个运行配置,提供正确的应用名,并且还有找到所有需要的plug-in。幸运的是,现在PDE可以处理所有的这些。你所要做的仅仅是在Plug-in Manifest编辑器的Overview页中点击Launch an Eclipse Application。你就能看到启动了一个基本的Workbench。(图 1)
图 1. 最简单的RCP应用
在Eclipse里,feature是plug-in的集合。Feature是可选的,但是Eclipse推荐你使用feature,这是因为如果你需要通过Eclipse的自动更新管理器来安装、更新你的应用,或者使用JNLP导出应用,feature就能帮助你做到这些。要创建feature,选择File > New > Project > Plug-in Development > Feature Project。一般feature的名字是你的plug-in项目名加上“-feature”,所以我们这里创建的feature就叫org.eclipse.ui.tutorials.rcp.part1-feature。点击Next来到Feature Properties页面,再点击Next,来到Referenced Plug-ins and Fragments 页面。选择org.eclipse.ui.tutorials.rcp.part1,点击Finish,这样feature项目就创建好了。
用Eclipse的话来说,product就是任何构成你的应用的东西,包括所有它所依赖的plug-in,运行应用的命令,以及使你的应用区别于其他应用的商标(图标等)。虽然你运行一个RCP应用并不需要定义product,但是这样做可以使得你应用脱离Eclipse运行变得更容易。这是Eclipse 3.1为RCP开发带来的重要改进。
许多复杂的RCP模版随着product一起提供,例如,“RCP Application with an Intro”和“RCP Mail”。更多的模版会在今后的版本中提供。Hello RCP这个模版没有定义成product,所以我们就为它建立一个product。
为了建立product,你首先为项目添加一个product定义文件。右键点击plug-in项目,选择New > Product Configuration。然后输入配置文件的文件名,比如part1.product。选择Use a launch configuration,和下拉列表中的Eclipse Application。(注意如果你在当前的workspace中有其他的plug-in项目,你有可能会看到一个不同的运行配置名。选取和你刚才运行的RCP plug-in相关的运行配置)然后点击Finish。这时会出现product配置编辑器。通过这个编辑器,你可以控制你的product中所需要的plug-in和商标。
在Overview页面中,输入Product Name,比如RCP Tutorial 1。选择This project configuration is based on features。然后选择New...按钮创建一个新的product。输入product的Defining Plug-in为org.eclipse.ui.tutorials.rcp.part1。输入Product ID,比如product,Product Application选择org.eclipse.ui.tutorials.rcp.part1.application。点击Finish。
在Eclipse 3.1中,如果你在输入Product Name前创建product,你会在Problems视图中看到错误。这个错误在你Synchronize后会消失。这是一个已知的bug,会在今后的版本中修复。
回到Product Configuration编辑器的Overview页面。点击product configuration链接或者选择Configuration页面,添加你的feature(org.eclipse.ui.tutorials.rcp.part1_feature)和RCP的feature(org.eclipse.rcp)。然后回到Overview页面,按 Ctrl+S或者File > Save保存。
这时,你应该测试你的product,确保它能正确运行。在Overview页面的Testing部分,点击Synchronize,然后点击Launch the product。如果运行正常,应用应该和刚才看到的结果一样。
所有这些都是为了能在用户对Java和Eclipse一无所知的情况下运行独立的应用。对于一个真实的应用,你可能提供由InstallShield这样的安装程序生成的可执行程序。这超出了本教程的范围,所以我们会用简单的方式来演示。
我们需要建立一个简单的Eclipse安装目录,这是因为Eclipse plug-in装载器希望所有的plug-in都在恰当的位置。这个目录必须包含可执行的Eclipse启动程序,配置文件和所有product需要的feature和plug-in。我们为此定义了足够的PDE信息。
在Product Configuration编辑器(不是Plug-in Manifest编辑器)中,点击Eclipse product export wizard。修改根目录为RcpTutorial1。然后选择Export Destination为Directory,并输入目录名,比如C:/Deploy。如果你正在建立一个开放源码的项目,你可以选择Include source code。最后点击Finish。
现在,应用就可以在脱离Eclipse的情况下执行。当你完成后,你应该得到下面的目录结构:
RcpTutorial1 | .eclipseproduct | eclipse.exe | startup.jar +--- configuration | | config.ini +--- plugins | | org.eclipse.core.commands_3.1.0.jar | | org.eclipse.core.expressions_3.1.0.jar | | org.eclipse.core.runtime_3.1.0.jar | | org.eclipse.help_3.1.0.jar | | org.eclipse.jface_3.1.0.jar | | org.eclipse.osgi_3.1.0.jar | | org.eclipse.rcp_3.1.0.jar | | org.eclipse.swt.win32.win32.x86_3.1.0.jar | | org.eclipse.swt_3.1.0.jar | | org.eclipse.ui.tutorials.rcp.part1_1.0.0.jar | | org.eclipse.ui.workbench_3.1.0.jar | | org.eclipse.ui_3.1.0.jar | | org.eclipse.update.configurator_3.1.0.jar +--- features +--- org.eclipse.ui.tutorials.rcp.part1_feature_1.0.0 +--- org.eclipse.rcp_3.1.0
在Eclipse 3.1,推荐的plug-in格式是一个jar文件。这在部署应用的时候可以节省存储空间。
本教程的以前版本使用批处理文件或shell脚本来启动你的RCP程序。 现在看来,这是一个不好的办法,因为你不能完全为你的应用定制商标信息。例如,你不能添加启动画面。所以务必使用Eclipse可执行的启动程序。
试试看吧!在Eclipse外执行可执行启动程序,看看它能不能工作。启动程序的名字(缺省是“Eclipse”)可以在product配置的时候在商标选择中设置。
在我写本教程的早些版本中,我收到邮件说他们由于这样或那样的原因不能运行例子。许多的意见已经在新的PDE设计中有所改善,所以没必要将它们列在这里。因此我现在将这一节暂时留着空白。如果你在运行应用时有任何问题,请告诉我,我将加以解决一般其他人能看到。
如果你正在将一个Eclipse 2.1版本的plug-in移植为Eclipse 3.1版本,你需要参考在线文档中所提到的一些问题。如果你是移植Eclipse 3.0版本的plug-in,那问题会少很多。更多的信息可参阅参考部分。
建议:当心不要使plug-in.xml和MANIFEST.MF的内容有所重复。一般不会这样,除非你将一个不使用MANIFEST.MF的老plug-in转换成使用MANIFEST.MF的,而且是手工编辑这些文件二没有借助于PDE。
结尾
在本教程的第一部分,我们看到建立一个Rich Client的简单应用需要哪些必要的步骤。下一部分将深入介绍那些由向导建立的类,比如WorkbenchAdvisor。所有的例子代码可以在这里找到。
Rich Client Platform (RCP) 使你可以创建出能和任何平台的原生应用匹敌的Java应用 。教程的第一部分向你介绍了用来创建最简单的RCP程序的所用到的平台和步骤。在第二部分中,我们将更详细地了解我们做了哪些,并且介绍一些配置类使得你可以控制RCP应用的外观和功能。
(译,本教材适用于Eclipse 3.0,并在不久为Eclipse 3.1作更新)
作者 Ed Burnette,SAS
译者 Cliff Liang,BeniSoft
2004年8月9日
在Eclipse 2.1中,Eclipse IDE的许多功能是由固定的代码实现的。这包括File菜单的名字和位置,Wrokbench窗口的标题,以及状态栏的存在与否。这对于IDE来说并没有什么不好,但是当有人使用Eclipse用作非IDE的程序时,这些内容就不那么合理了。虽然所有的源代码都是公开的,但是要找到这些修改的地方仍然不是那么的容易。所以,在Eclipse 3,设计者重构了API使得用户界面的这些部分可以通过公有的API来控制。
到目前为止,Eclipse 3引入了一个全新的WorkbenchAdvisor类和一组*Configurer接口。其中对RCP开发人员最重要的类就是WorkbenchAdvisor。你可以在你的RCP应用中继承WorkbenchAdvisor,重写一些方法来设置任何你需要的选项。在第一部分,我们实现了一个简单方法,getInitialWindowPerspectiveId
,它是用来返回一个应用唯一的透视图(视图,编辑器,和菜单)。
在下一节,我们来看看其他的一些advisor方法。如果你想看第二部分的代码,可以在这里下载它们。
下面,我们就先来对Application,Workbench,和Workbench Window 作 一个清晰的了解。
Application是一个你创建的作为RCP主程序的类。你可以认为它是程序的控制器。就象Model 2架构中的控制器一样,它很短小,并且在不同的项目中都差不多。它所做的就是创建一个Workbench,并交给Workbench一个Workbench Advisor。
对你来说,Workbench是作为RCP框架的一部分被声明和维护的。一个Application只有一个Workbench,但是一个Workbench可以有超过一个可见的顶层Workbench Window。例如,在Eclipse IDE中,当你第一次启动Eclipse时,你会看到一个Workbench Window,但是如果你选择Window > New Window,就会出现第二个窗口,这样就有两个Workbench Window,而还是单独一个Workbench。
图1显示了Application,Workbench,以及Workbench Window之间的关系。
图1 一个RCP程序有一个你定义的Application类,和一个框架提供的Workbench类。一般只有一个Workbench Window,但是框架支持多个Workbench Window。
好,现在我们就来试试改变一下Workbench Window的样子。
第一部分的那个例子含有状态栏,工具栏以及其他的一些可视元素,但是这些并没有被使用。我们可以争辩说这些元素在缺省条件下应该不显示,但是由于某种原因,情况并不是这样,所以如果你不想要它们,你不得不自己把它们关掉。并且在那个例子中窗口没有标题,大小也比需要的大很多。设置这些内容的一个合适的地方就是WorkbenchAdvisor
的preWindowOpen
方法,请看下面代码1。
代码 1. preWindowOpen 例子.
public void preWindowOpen(IWorkbenchWindowConfigurer configurer) { super.preWindowOpen(configurer); configurer.setInitialSize(new Point(400, 300)); configurer.setShowCoolBar(false); configurer.setShowStatusLine(false); configurer.setTitle("Hello, RCP"); }
注意Configure接口(这里就是IWorkbenchWindowConfigurer
)是如何被传递给advisor方法的。你可以调用Configure接口中的方法来设置选项。本教程不会详细介绍这些接口,需要的话你可以参考它们的Javadoc。图2显示了最后的效果。
图 2. 带有标题的Workbench window。其他没有用到的控件被关闭了,标题是使用WorkbenchAdvisor的preWindowOpen事件设置的。
既然RCP是新的技术,文档还不多,我们先来看一下有关WorkbenchAdvisor
类的背景信息。Platform在Workbench生命周期中的各个点调用这个类的方法。这个类同时还在事件循环中提供了一种处理异常的方法,以及向Workbench提供诸如缺省透视图这样的重要参数。首先我们来看一下Workbench生命周期中的事件。
为什么WorkbenchAdvisor
不是一个接口?你可能注意到WorkbenchAdvisor
是一个虚类。对于大多数情况,Eclipse API使用接口,避免使用抽象类,和实现这些接口的基类。在这里,开发者打算使用总是由RCP应用实现的WorkbenchAdvisor
,基类不包含任何重要功能,并且在今后会添加新的方法(这些在使用接口的情况下是比较困难的)。所以这是一个经过考虑的设计选择。更多的内容可以参考教程后面有关Java API的文章。
Workbench只有一个,虽然你可以打开不止一个Workbench Window,但一般,Workbench Window也只有一个。图3显示了在Workbench和Workbench Window生命周期中最重要的事件。表1显示你在WorkbenchAdvisor
子类中可以重写来处理Workbench生命周期事件的所有方法。表2显示那些处理Workbench Window生命周期事件的方法。
图 3. Workbench和Workbench Window生命周期中的重要事件。这些事件在WorkbenchAdvisor
中都有相应的方法,Platform调用这些方法从而执行你的定制代码。
表 1. Workbench 生命周期事件处理方法,它们定义在org.eclipse.ui.application.WorkbenchAdvisor
中。
方法 | 描述 | 参数 |
---|---|---|
initialize | 第一个被调用,用来初始化,比如解析命令行,注册适配器,声明图像等时。 |
IWorkbenchConfigurer |
preStartup | 在初始化结束,但是在第一个窗口打开前调用。可以被用来设置一些选项来影响初始打开的编辑器和视图。 |
|
postStartup | 在所有窗口已经被打开或恢复后,但是在事件循环开始前调用。它可以被用来启动自动处理器,打开提示或其他窗口。 |
|
preShutdown | 在事件循环结束后,但在任何窗口被关闭前调用。 |
|
postShutdown | 在关闭Workbench过程中,所有窗口被关闭后调用。它可以被用来存储当前的应用状态和清理任何由 |
表 2. Workbench window 生命周期事件处理方法,它们定义在org.eclipse.ui.application.WorkbenchAdvisor
.中。
方法 | 描述 | 参数 |
---|---|---|
preWindowOpen | 在Workbench Window的构造器中调用。可以使用这个方法来指定窗口是否有菜单栏。然而,窗口的widget还没有创建,因此在这个方法中不能引用它们。 |
IWorkbenchWindowConfigurer |
fillActionBars | 紧接着 |
IWorkbenchWindow , IActionBarConfigurer , flags |
postWindowRestore | 当一个窗口从保存的状态恢复时,但在打开前,被调用。 |
IWorkbenchWindowConfigurer |
postWindowCreate | 在窗口从保存状态恢复,或从scratch中创建后,但在打开前,被调用。 |
IWorkbenchWindowConfigurer |
openIntro | 在窗口打开前一刻被调用,它用来创建introduction组件(如果有的话)。 |
IWorkbenchWindowConfigurer |
postWindowOpen | 紧接着Workbench Window被打开后调用。它被用来组装窗口的widget,例如设置标题或修改它的大小。 |
IWorkbenchWindowConfigurer |
preWindowShellClose | 在Workbench Window被关闭前调用(从技术上来说,是在它的shell被关闭前)。这是唯一能够终止关闭动作的方法,所以,它可以用来显示“你确定吗”这样的对话框。 |
IWorkbenchWindowConfigurer |
postWindowClose | 在Workbench Window关闭后调用。它被用来清理任何由 |
IWorkbenchWindowConfigurer |
事件循环是在Workbench生命周期中运行事件最长的代码。它处理所有的用户输入,并将它们派发到正确的处理方法中。RCP提供了一组方法来处理应用崩溃以及在空闲时间调用(见表3)。
表 3. org.eclipse.ui.application.WorkbenchAdvisor
中定义的事件处理方法
方法 | 描述 | 参数 |
---|---|---|
eventLoopException | 当事件循环中出现一个unchecked异常时调用。缺省实现是记录这个错误。 |
Throwable |
eventLoopIdle | 当事件循环没有什么需要做的时候调用。 |
Display |
接下来,你可以实现一些方法供Platform调用,使得Platform获取关于你应用的信息(见表4)。最重要的(并且也是唯一必需的)是getInitialWindowPerspectiveId
。我们在第一部分中使用它来返回起始透视图的ID。
表 4. org.eclipse.ui.application.WorkbenchAdvisor
定义的信息请求
方法 | 描述 | 参数 |
---|---|---|
getDefaultPageInput | 返回新的Workbench页面的缺省输入,缺省值是null。 |
|
getInitialWindowPerspectiveId | 返回新创建的Workbench Window的初始透视图。这个方法必须提供。 |
|
getMainPreferencePageId | 返回第一个显示的首选参数页。缺省是null,这意味着首选参数页按字母顺序排序。 |
|
isApplicationMenu | 返回是否是应用菜单。这和OLE相关,详细参考Javadoc。 |
IWorkbenchWindowConfigurer , String |
上面的WorkbenchAdvisor事件对大多数应用来说是足够了,但是在某些情况,RCP又提供了两个方法来控制你的应用窗口和控件如何被创建。它们被列在表5,但是我觉得很多程序不需要用到这些。
表 5. org.eclipse.ui.application.WorkbenchAdvisor
提供的高级方法
方法 | 描述 | 参数 |
---|---|---|
createWindowContents | 创建一个窗口的内容。重写这个方法来定义自定义的内容和布局。 |
IWorkbenchWindowConfigurer , Shell |
openWindows | 在启动时打开所有Workbench Window。缺省实现会恢复前面存储的Workbench状态。 |
国际化(缩写I18N)允许你的应用可以面向更广泛的市场。第一步很简单,将显示给用户的文本信息从你的代码提取出来,放置到一个标准格式的properties文件中。即使你没有打算使你的代码支持多种语言,将文本信息和代码分离可以使你更容易地检查拼写错误,语法,以及措词。
在Eclipse中,并没有什么魔法来处理文本信息,你仅仅使用普通的Java的resource bundle机制。Eclipse IDE提供了一个不错的Externalization的向导来使工作变得容易些。你可以看参考部分的文章来详细了解如何使用这个向导。
当你在一段新的代码时,你常常会写固定的文本信息以便这段代码能工作。例如,我们有
configurer.setTitle("Hello, RCP");
一旦你让这段代码工作后,你应该养成习惯使用Externalization向导将这些字符串提取出来。在项目上点击鼠标右键,选择Source > Find Strings to Externalize...。任何需要注意的源文件会被列出来。选择一个,按按钮Externalize...打开Externalization向导。在那儿,向导会将你的代码转换成一个resoure bundle引用。或者,你可以右键点击一个源文件,选择Source > Externalize Strings...。当你完成,你的代码看起来象下面那样:
configurer.setTitle(Messages.getString("Hello_RCP")); //$NON-NLS-1$
字符串$NON-NLS-1$
用来提示编译器和Externalization向导,这一行的第一个字符串是一个标签或关键字,不需要本地化。
当然你会有一个标准格式的.properties文件,它包含了你所有文本信息的键和值。在示例程序中,你会发现一个RcpTutorial.properties的文件,它包含了
Hello_RCP=Hello, RCP
最后,向导会建立一个封装Java resource bundle的类来装载.properties file,并查找值。
为了完成替代,可以使用标准的java.text.MessageFormat
类。它的format()
方法类似于C语言的sprintf
函数,除了不是使用由百分号来控制格式,而是用包含序号的花括号对。这里有一个来自例子plug-in的XMLStructureCreator
类的例子:
bodynode.setName(MessageFormat.format("{0} ({1})", new String[] {XMLCompareMessages.getString("XMLStructureCreator.body"), Integer.toString(fcurrentParent.bodies)})); //$NON-NLS-2$ //$NON-NLS-1$
这并不是一个好的例子,因为格式字符串本身(译,这里指的是“{0} ({1})”)也应该是定义在一个消息文件中。然而,用于其他程序的消息(命令,关键字,脚本,等)不应该存在在消息文件中。
为了防止一行变得太长,你可能需要创建帮助方法。帮助方法的例子可以看org.eclipse.internal.runtime.Policy
。
在本教程的第二部分中,我们看了RCP重构后的新API,这些API允许你开放自定义外观的客户端Java程序。下一部分将深入讨论定义和建立菜单和工具栏。所有的例子代码可以在这里得到。你可以使用Eclipse的内置CVS客户端下载源程序。
Rich Client Platform (RCP)使你可以从Eclipse中选择功能用在你的应用中。本教程的第一和第二部分介绍了平台以及它所提供的部分配置类。第三部分讨论如何增加功能,例如菜单,视图,帮助文件等。
(译,本教材适用于Eclipse 3.0,并在不久为Eclipse 3.1作更新)
作者 Ed Burnette, SAS
译者 Cliff Liang,BeniSoft
2004年7月28日
前面两个部分我们讨论了怎样从平台挪走一些东西-关掉工具条,去掉菜单等等。从这部分开始,我们就来看看怎么把这些东西放回去. 你可以从Eclipse 项目下载教程中的所有源代码。
我们先从视图开始。Eclipse 的 Plug-in 开发环境提供一套很好的extension模板,使你可以很快地写出例子视图,编辑器,菜单和其他组件。遗憾的是,对于RCP开发来讲这些代码几乎没什么用处,因为这些代码引入了对IDE , 资源包和plug-in等的依赖。
总的来说,规则是涉及资源的任何东西都不是给RCP开发者使用的,因为其使用特别的代码以及依赖所在的workspace。因此,如果你看到org.eclipse.core.resources plug-in
在你所依赖的列表里面,或者看到从那个包导入了某些类,你可能就已经做错了。虽然这不是一条固定和快速的判断标准,但是所有的资源都应该看成为Rich Client Platdform的可选 部分.。
如果要不使用模板创建一个视图,你可以使用 plug-in 的Manifest编辑器提供的基于schema的extension向导(Extensions pane > Add > Generic Wizards > Schema-based Extensions)或者在Source Pane中编辑XML文件。采用以上任何一种方式,你都可以得到类似这样的extension XML:
视图的category () 使你可以在Show Views对话框中组织你的视图。class属性()所指定的类 继承了 ViewPart
抽象类。如下所示:
public class SampleView extends ViewPart { public static final String ID_VIEW = "org.eclipse.ui.tutorials.rcp.part3.views.SampleView"; //$NON-NLS-1$ private TableViewer viewer; public SampleView() { } public void createPartControl(Composite parent) { viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); viewer.setContentProvider(new ViewContentProvider()); viewer.setLabelProvider(new ViewLabelProvider()); viewer.setInput(this); } public void setFocus() { viewer.getControl().setFocus(); } }
定义一个以 ID_
开头的常量 () 是Eclipse源代码中经常使用的一种常规方式。这里,我们还在plug-in的manifest中使用它。它还在将来需要引用该视图时使用.
这个类最重要的部分是createPartControl
方法 ()。在这里,你可以创建用于组成视图的JFace或者SWT控件。源代码的其它部分可以在例子项目中找到。视图编程超出了本教程的范围,但你可以在参考部分找到更多相关信息。
如果你现在运行代码,你不会看到任何不同的东西。为什么呢?因为你的新视图在被加入当前透视图之前不会显示。你可以通过代码或者为org.eclipse.ui.perspectiveExtensions实现extension添加视图。我们将使用前一种方式,因为这种方式更加灵活。为此,我们回过头去看一下刚才定义的RcpPerspective
类并且做一些修改:
public class RcpPerspective implements IPerspectiveFactory { public static final String ID_PERSPECTIVE = "org.eclipse.ui.tutorials.rcp.part3.RcpPerspective"; //$NON-NLS-1$ public RcpPerspective() { } public void createInitialLayout(IPageLayout layout) { layout.setEditorAreaVisible(false); layout.addView( SampleView.ID_VIEW, IPageLayout.TOP, IPageLayout.RATIO_MAX, IPageLayout.ID_EDITOR_AREA); layout.addPerspectiveShortcut(ID_PERSPECTIVE); layout.addShowViewShortcut(SampleView.ID_VIEW); } }
注意:
再次强调,养成习惯把所有的字符串定义成常量,尤其是id。 |
|
平台支持编辑器,但是我们在这个例子中不使用它。因此,你需要把编辑器区域关掉,这样就不会在你的Workbench窗口中看到一个大块空白。 |
|
这是这个类最重要的部分。它把视图加到透视图,视图缺省是可见的。位置参数定义了这个视图在编辑器区域上方,并且占Workbench Window的全部大小。这看起来可能有点奇怪,因为我们没有编辑器区域,但编辑器区域还是存在的,虽然它不可见。当你给应用添加多个视图时,你可以在这里定义缺省的视图堆叠和布局方式。 |
|
如果你实现 |
|
同样,仅用于视图。 |
如果要在用户下次打开你的应用时记住上次的布局和窗口大小,在WorkbenchAdvisor
的initialize
方法里加上configurer.setSaveAndRestore(true);
。你可以在例子项目中找到一个例子。
缺省情况下,视图是可以移动,改变大小,并且是可以关闭的。但是你常常不需要这种灵活性。例如,如果你正在为普通用户写一个订单录入应用,你不想回答如果用户不小心关闭了表格视图该怎么办这样的问题。为此,Eclipse 3.0引入了固定透视图和固定视图的概念。
固定视图就是不能被关闭的视图。视图的标题栏没有关闭按钮。为了创建这样的视图,你需要使用IPageLayout
定义的setFixed()
方法。
一个更好的办法就是使用固定透视图。固定透视图中,所有的视图都是固定的,此外,它还禁止它们移动和改变大小。要使用固定透视图,只要简单地在透视图定义中设置属性fixed="true"
,例如:
fixed="true" class="org.eclipse.ui.tutorials.rcp.part3.RcpPerspective" id="org.eclipse.ui.tutorials.rcp.part3.RcpPerspective">
使用固定透视图并关闭快捷栏,你可以使用户始终使用这个透视图,并且完全向用户隐藏它们。
RCP的一个需求就是允许你配置所有的菜单。在一个RCP应用添加菜单有两个方法:
WorkbenchAdvisor.fillActionBars
org.eclipse.ui.actionSets
in the plug-in manifest fillActionBars是引用内建Workbench action的唯一方式。其他action都可以通过actionSets这个extension point来实现。这两个方法我们都将在这里演示。虽然例子应用没有使用工具栏,但是它们和菜单非常类似。
首先,我们来看看fillActionBars
:
public void fillActionBars( IWorkbenchWindow window, IActionBarConfigurer configurer, int flags) { super.fillActionBars(window, configurer, flags); if ((flags & FILL_MENU_BAR) != 0) { fillMenuBar(window, configurer); } }
fillActionBars使用参数flags()来指定代码应该做什么。在菜单栏,工具栏,状态栏都有flag位,甚至还有一个位用来指定它是否是用于preference对话框的伪请求(
FILL_PROXY
)。我在用这些flag时有过糟糕的经历,所有例子代码调用一个帮助方法fillMenuBar来做实际的菜单填充。下面是fillMenuBar的代码。
private void fillMenuBar( IWorkbenchWindow window, IActionBarConfigurer configurer) { IMenuManager menuBar = configurer.getMenuManager(); menuBar.add(createFileMenu(window)); menuBar.add(createEditMenu(window)); menuBar.add(createWindowMenu(window)); menuBar.add(createHelpMenu(window)); }
这个例子中,我们要建立四个顶层菜单:File,Edit,Window,和Help。它们对于于Eclipse IDE中相同名字的菜单。对于一个实际应用,你可能不需要所有的,或者你想用别的名字。看下面的图1。
图 1. Workbench的菜单栏在WorkbenchAdvisor
的fillActionBars
方法中定义,并且添加所有扩展org.eclipse.ui.actionSets
的plug-in的manifest中定义的菜单。
这些方法的代码可以在例子项目找到。我们来仔细看看其中之一,File菜单:
private MenuManager createFileMenu(IWorkbenchWindow window) { MenuManager menu = new MenuManager(Messages.getString("File"), //$NON-NLS-1$ IWorkbenchActionConstants.M_FILE); menu.add(new GroupMarker(IWorkbenchActionConstants.FILE_START)); menu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); menu.add(ActionFactory.QUIT.create(window)); menu.add(new GroupMarker(IWorkbenchActionConstants.FILE_END)); return menu; }
所有的菜单都以同样的方式工作。首先,你创建一个为菜单MenuManager () ,它使用一个消息文件来查找实际用来显示给用户的名称。然后你添加所有的菜单项,并返回MenuManager。关于更多定义视图和菜单的信息,你可以看参考部分。接下来,你创建一个占位符 (),在那儿可以其他plug-in可以添加额外的菜单项,以及一个由Workbench提供的动作:Quit action ()。ActionFactory
和ContributionItemFactory
的Javadoc定义了所有Workbench支持的action。
当你在Eclipse IDE中完成象上面这样的工作,你可以使用大量用于菜单和工具栏的标准占位符名。使用这些预定义的组,为Eclipse IDE设计的菜单和工具栏也可以用于你的RCP应用。这些内容在IWorkbenchActionConstants
的Javadoc中可以找到,但是没有有关它们顺序的说明。这个教程的例子代码是根据Eclipse IDE使用的IDEWorkbenchAdvisor
类的Javadoc创建的。
RCP一个很cool的功能就是帮助系统。你只要提供XML格式的目录结够,以及HTML格式的内容,就可以提供给用户一个可以查找的帮助系统,整个过程你不需要任何代码。首先,你在你的plug-in的manifest中添加一个extension,就象下面一样:
然后你创建一个目录文件(这个例子中是book.xml)定义帮助标题的层次结构。不是所有的标题都必需在这个文件中,但是鼓励这样做。这儿有一个例子:
参考部分提供了更多撰写,组织帮助文件,包括国际化的资料。
当你调试或部署一个包含帮助的RCP应用时,你需要包括几个和帮助相关的plug-in。这儿是目前这些plug-in的列表(可能在今后的版本会有所改变)。
org.apache.ant
org.apache.lucene
org.eclipse.help.appserver
org.eclipse.help.base
org.eclipse.help.ui
org.eclipse.help.webapp
org.eclipse.tomcat
在例子代码中,你可以看到createHelpMenu()用来添加Help Contents的action到你的Help菜单。当你选择它时,这个action会弹出一个帮助浏览器,就象下面图2。
图 2. Rich Client Platform提供了功能丰富的在线帮助框架。你所需要做的就是提供帮助的内容。
当你添加HTML文件,图标,帮助目录等资源到plug-in时,别忘了更新你的build.properties文件,添加这些在plug-in运行时需要的文件,目录。这儿是一个更新后的build.properties,它包含例子中需要的所有文件。
bin.includes = plugin.xml,/ *.jar,/ part3.jar,/ plugin.properties,/ book.xml,/ html/,/ icons/ source.part3.jar = src/
在这部分中,我们创建一个RCP应用,并添加了一个简单的视图,一些菜单,和帮助文件。你可以用这个例子作为你自己项目的参考。这部分的所有代码可以在这里找到。你可以使用Eclipse内置的CVS客户端来下载它们。
贡献你!你已经可以开放自己Rich Client Platform应用。你可以看看下面的参考信息,站点和邮件列表。