免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4787 | 回复: 0

SWT入门教程 [复制链接]

论坛徽章:
0
发表于 2007-01-12 10:16 |显示全部楼层

Eclipse 的 Rich Client Platform 入门
开始之前
关于该教程
作为由两部分组成的系列文章的第 1 部分,本教程探索了 Eclipse 的 Rich Client Platform(RCP)。并用一个样例应用程序向您展示如何装配 RCP,从而为您自己的商业应用程序创建了一个一流的客户端接口。该应用程序为 Google API 创建了一个前端,并提供了查询和显示搜索结果的能力。通过运行演示 RCP 中某些技术的应用程序,使您了解该平台及其在您的某些项目中的效用。
要完成本教程,您需要理解如何操作 Eclipse 3.0 并具备一些 Java 的应用知识。但并不需要您有 Eclipse 插件开发的背景,或者了解诸如 Standard Widget Toolkit(SWT)和 JFace 之类的技术。您将通过本课程详细探索所有这些补充性技术。在简短地介绍了这些技术之后,本教程将讨论代码和支持性文件,使您掌握如何构造 RCP 应用程序。如果不熟悉 Eclipse 或者它的补充性技术,请参阅本教程结尾的
参考资料
,以获取更多的信息。
工具
通过该系列文章,您将详细探索 Eclipse 插件开发环境的各个领域。尽管没有先决条件,但是如果您下载、安装并配置 Eclipse 3.0、1.4 Java 虚拟机和 Apache Ant,将会发现本教程还是很容易理解的。如果没有安装这些工具,请引用、下载并安装下列资源:
Eclipse 3.0 可以从
http://www.eclipse.org/downloads/index.php
中获得。
Java 2 标准版,软件开发包(SDK)可以从
http://java.sun.com/j2se/1.4.2/download.html
中获得。
Apache Ant 1.6.1 可以从
http://ant.apache.org/
中获得。
关于作者
Jeff Gunther 是
Studio B
的作者,还是 Intalgent Technologies 的总经理和创始人,这是一家新兴的采用 Java 2 企业版和 Lotus Notes/Domino 平台的软件产品和解决方案的提供商。Jeff 是一个应用程序和基础设施架构师,具有架构、设计、开发、部署和维护复杂软件系统方面的经验。他在许多方面都有丰富经验,其中包括运行于多种平台(从 Web 服务器到嵌入式设备)之上的软件的整个生命周期开发。您可以通过
jeff.gunther@intalgent.com
与他联系。

Eclipse 和 RCP 的概述
Eclipse 的成熟
在过去的几年中,Eclipse 取得戏剧性的发展,并且已经成长为一个强大的开发环境。尽管您可以将 Eclipse 看作是传统意义上的一个用于软件开发的集成开发环境(IDE),但是 Eclipse 的 3.0 版将拓宽该平台在市场上的适用范围。大约一年前,Eclipse 社区的成员认识到可以在非 IDE 应用程序中使用 Eclipse IDE 的许多元素。当构造商业应用程序时,开发人员可以使用简洁的插件体系结构、作出响应并且具有本地样式的用户界面,以及易于使用的帮助系统。通过利用公共框架开发商业应用程序,开发人员可以将他们的精力集中在解决应用程序的特定需求上,而不是浪费时间去重新构造核心组件集。Eclipse 3.0 milestone 5 将开发社区引进了 RCP。
什么是 RCP
在浏览器大战的日子里,许多开发人员和用户都对桌面 Web 浏览器缺乏创新和进步而感到失望。尽管 Web 浏览器允许机构为大量的用户部署后台办公应用程序,但试图提供支持多个操作系统上的多个浏览器的可用接口,将加重开发人员和管理人员的负担。RCP 是一个令人激动的概念,它寻求满足对单一跨平台环境的需要的解决方法,以创建高交互性商业应用程序。
实质上,RCP 提供了一个通用的 Eclipse 工作台,开发人员可以扩展该工作台来构造自己的应用程序。一个应用程序至少包括一个定制插件,并且可以使用与 Eclipse 3.0 IDE 相同的用户界面元素。在转向对如何创建插件的讨论之前,应该让您自己熟悉一下 Eclipse 用户界面的基本元素,如图 1 所示。
1. Eclipse 用户界面的基本元素
该环境的基本元素包括:
Workbench(工作台) —— 用于所有窗口的拱形容器。
Perspective(透视图) —— 用于所有已打开的视图和编辑器的可视化容器。
View(视图) —— 显示特定类型资源的可视化容器。 通常,一个视图包括一个数据网格或者树结构。在图 1 中, 任务视图是一个视图实例,可以在 Java 透视图中使用它。
Short Cut Bar(快捷方式栏) —— 图标的集合,允许用户快速访问不同的透视图。
Menu Bar(菜单栏) —— 内容敏感动作的集合,为用户提供执行某些预定义功能的能力。
Tool Bar(工具栏) —— 内容敏感动作的集合,允许用户执行某些预定义的功能。在工具栏中发现的所有项都显示在菜单栏中。
Editor(编辑器) —— 编辑器是用户显示和操作数据的主要工具。在 Eclipse IDE 环境中,开发人员使用编辑器编辑 Java 源代码。
标准窗口小部件工具箱和 JFace
如果查看组成 Eclipse 平台的源代码,你会注意到,它并没有使用 Java 标准窗口小部件工具箱。在 Eclipse 平台开发期间,该项目产生两个用户界面工具箱,您可以在 Eclipse 项目以外的地方使用它们。这些工具箱包括:
标准窗口小部件工具箱(Standard Widget Toolkit,SWT) —— SWT 提供一个与平台无关的 API,并与操作系统的本地窗口环境紧密集成。SWT 的方法向 Java 开发人员提供了一个跨平台的 API,用于实现“感觉上”类似于本地桌面应用程序的解决方案。该工具箱克服了开发人员在使用 Java 抽象窗口小部件工具箱(AWT)或者 Java 基础类(JFC)时面临的许多设计和实现权衡。
JFace —— JFace 工具箱是一个与平台无关的用户界面 API,它扩展了 SWT,并能与 SWT 交互操作。该库提供了一个组件集合和帮助者工具,在开发 SWT 用户界面时,可以用它来简化许多公共任务。该工具箱包括许多工具类,它们扩展 SWT 来提供数据观察器、向导和对话框组件、文本操作,以及图像和字体组件。
在开发 RCP 应用程序期间,可以大量使用 SWT 和 JFace 类。请参阅
参考资料
,以获得关于这两个工具箱的更多信息。
Eclipse 插件体系结构
由于受到其祖先 IBM Visual Age for Java 的影响,Eclipse 平台也很容易扩展。下图 2 阐述了 Eclipse 体系结构的主要组件。
2. Eclipse 体系结构的主要组件
除了组成 Eclipse 平台运行时的基本文件之外,Eclipse 的所有功能都是通过使用插件来实现的。插件是开发人员使用的基本构造块,用于向环境添加新的功能。(请参阅
参考资料
,获取一篇关于开发 Eclipse 插件的 developerWorks 精彩文章。)Eclipse 运行时负责管理工作台内部插件的生命周期。特定环境的所有插件都位于某一插件文件夹中,而该文件夹位于 RCP 应用程序的目录结构中。当执行操作时,Eclipse 运行时将发现所有可用插件,并使用该信息创建一个全局插件注册表。
如果需要让插件参与到工作台内,则必须定义一个扩展集合。扩展可以直接将功能添加到基础的通用工作台中,或者扩展其他已有的扩展。每个这样的扩展都是在插件的清单文件中定义的。该 XML 文件描述了 Eclipse 运行时内部的所有扩展是如何相互操作的,并且定义了必需的依存关系。下一节将更为详细地介绍插件清单及其标签。
RCP 入门
实现 RCP 应用程序的步骤
在介绍在 Eclipse 内部开发 RCP 应用程序的细节之前,我们来回顾一下实现这种类型项目的一般性步骤。
确定扩展点。
定义插件清单。
实现扩展。
定义 WorkbenchAdvisor 类。
定义 Application 类。
导出应用程序。
本节讨论了如何访问插件开发环境,同时还介绍了插件清单。
使用插件开发环境
Eclipse IDE 的组件之一是一个称为插件开发环境(Plug-in Development Environment,PDE)的特定透视图。该透视图为您提供了创建和包装定制 Eclipse 插件或者 RCP 应用程序所需要的所有东西。您可以通过实现下列步骤来访问该透视图:
从您的工作站上启动 Eclipse 3.0。
从菜单栏选择 Window > Open Perspective > Other。该动作将通过选择透视图对话框来提示您如何操作,如图 3 所示:
3. 选择透视图对话框
从透视图列表选择 Plug-in Development,然后点击 OK ,出现 PDE 透视图,如图 4 所示:
4. PDE 透视图
创建项目
利用在 Eclipse 中打开的 PDE 透视图完成下列步骤,以创建一个新的项目:
从菜单栏选择 File > New > Plug-in Project ,以显示 New Plug-in Project 向导,如图 5 所示:
5. New Plug-in Project 向导
在 Project name 字段内键入 Google
保存该页的默认值并点击 Next ,继续查看插件内容页面,如图 6 所示:
6. 插件项目内容页面
在 Class Name 字段中键入 com.ibm.developerworks.google.GooglePlugin,然后点击 Next ,出现模板页面。
保存该模板页面的默认值,然后点击 Finish
理解插件清单
在您完成 New Plug-in Project 向导之后,就将一个称为 Google 的项目添加到了包浏览器中,出现一个标题为“Overview”的页面,如图 7 所示。
7. Welcome to Google Plug-in
该页面是一个用来编辑已生成插件清单的强大工具。插件清单负责定义资源、依存关系和 Eclipse 运行时将要管理的扩展。所有项目的插件清单都位于该项目的根目录内,该目录名为 plugin.xml。编辑器底部的每个标签都向您提供了一个访问和操作该文件的特定部分的简便方法。
plugin.xml 标签允许您观察编辑器生成的每个部分的 XML。例如,下面您将看到 New Plug-in Project 向导最初生成的插件清单的内容。
   id="Google"
   name="Google Plug-in"
   version="1.0.0"
   provider-name=""
   class="com.ibm.developerworks.google.GooglePlugin">
      
        
               
                        
               
        
        
               
               
        
      
在进行本文的讨论期间,主要使用 plugin.xml 视图来编辑插件清单。尽管对于了解插件清单的结构来说,编辑器是一个很有用的工具,但是您必须了解它生成的一些标签,以及它们是如何帮助构成完整的插件的。接下来的两组讨论回顾了插件清单的每个标签,并解释了它们的用途。
使用插件清单标签
要创建基本的 RCP 应用程序,则需要向清单中添加一些额外的内容。通过使用插件清单编辑器的 plugin.xml 标签,在编辑器内部修改 XML,从而反映下列变化:

1      
2      
3      
4          id="com.ibm.developerworks.google"
5          name="Google Plug-in"
6          version="1.0.0"
7          provider-name=""
8          class="com.ibm.developerworks.google.GooglePlugin">
9
10              
11                     
12                           
13                     
14              
15
16              
17                     
18                     
19               
20
21              
22                     point="org.eclipse.core.runtime.applications">
23                     
24                             
25                     
26               
27
28               
29                     
30                            ="com.ibm.developerworks.google.GooglePerspective"
31                     name="Google"
32                            class="com.ibm.developerworks.google.GooglePerspective"/>
33              
34           
35      
接下来,我们将详细研究这个插件清单。
逐步分析插件清单
从  元素开始,第 3 至 8 行定义了插件清单的主体。这个基础标签包括该插件的所有扩展、扩展点、依存关系和运行时约束。而且, 标签具有下列 5 个属性:
name —— 该属性定义了插件的一般名称。
id —— 该属性为插件定义了一个惟一标识符。为了减少任何命名冲突,您应该从插件作者的 Internet 域名导出该属性。在该实例中,实例的 id 已经被改为 com.ibm.developerworks.google。该实践与其他的 Java 命名约定是一致的,例如类的包装。
version —— 该属性以 major.minor.service 的格式定义了插件的版本。
provider-name —— 该属性定义了插件的作者。
class —— 该属性定义了插件类的名称。尽管定义了插件类,但 RCP 应用程序在执行期间并不使用该类。
第 10 至 14 行定义了插件清单的运行时部分。与 Java 应用程序中类路径的概念类似,这部分定义了在执行期间所必需的所有本地 Java 库。可以通过使用  元素将每一个 Java 库列在  元素中。该 library 元素可以包括一系列嵌套的  元素。每个 export 元素都为该特定库定义了导出掩码。
第 16 至 19 行包含一个  元素,该元素定义了对其他插件的所有依存关系。可以通过使用单个  元素逐条列举每个插件。
第 21 至 37 行定义了 RCP 应用程序将使用的两个  元素。下面一组讨论回顾了扩展和扩展点的基本概念。 元素具有下列三个属性:
point —— 该属性定义了对正在进行配置的扩展点的引用。
id —— 该可选属性为扩展点配置实例定义了一个标识符。
name —— 该可选属性为扩展定义了一个一般名称。
理解扩展
正如前面在
Eclipse 插件体系结构
部分提到的,Eclipse 平台使用了一个相对较小的运行时核心和一个精致的插件体系结构,因此,它是高度可扩展的。可以通过使用插件为运行时核心添加新的功能。每个插件都可以包含任何数目的扩展,而且可以使用扩展点对它们进行集成。同样,插件也可以定义自己的扩展点,其他开发人员可以在自己的插件或者 RCP 应用程序中使用这些扩展点。
检查前面给出的插件清单的两个  元素。

1 ...
2              
3                      point="org.eclipse.core.runtime.applications">
4                       
5                              
6                       
7               
8
9               
10                     
11                             id="com.ibm.developerworks.google.GooglePerspective"
12                             name="Google"
13                             class="com.ibm.developerworks.google.GooglePerspective"/>
14              
15 ...
第 2 至 7 行通过 org.eclipse.core.runtime.applications 扩展点定义了第一个扩展。 而该扩展为 RCP 应用程序声明了一个入口点。在该扩展元素内部,定义了一个  元素。在标签内部有一个  元素。而  元素又包括一个类名称,RCP 应用程序启动时会执行该类。第二个扩展点是在第 10 至 17 行之间定义的。该扩展通过一个标题为 org.eclipse.ui.perspectives 的扩展点定义了一个透视图,并将该透视图添加到普通的工作台上。下一节将详细探讨透视图的使用。
关于 Eclipse 3.0 提供的各种类型的扩展点的更多信息,请参阅
参考资料

定义透视图
透视图概述
Eclipse 工作台内的透视图是用于所有已打开视图和编辑器的可视化容器。在前面的
使用插件开发环境
讨论中,您打开了一个特定的称为 PDE 的透视图,以启动 Google 插件项目。该透视图是特别设计的,它向开发人员提供了一个用来开发定制插件的工具集。透视图的最终用户可以看出,PDE 的创建者在工作台内工具的位置和布局方面投入很多关注。当您在自己的 RCP 应用程序中创建透视图时,请考虑下列情况:
定义透视图的目的 —— 由于 Eclipse 工作台每次只显示一个透视图,您可能希望将应用程序的逻辑和功能区域分组到统一的透视图中。该方法将最小化用户为完成特定任务而在不同透视图之间进行切换的需要。当您定义每个透视图的目的时,还要牢记,不能在不同的透视图之间共享视图或者编辑器。应用程序将包含的透视图的数目在很大程度上取决于该应用程序的大小和复杂性。对于我们的 Google 应用程序实例来说,最初只定义了一个透视图。
定义透视图的行为 —— 取决于您的应用程序,透视图具有它自己的集合视图、编辑器和动作,可以设计它们来执行不同的功能。例如,Eclipse 3.0 中的 Java 浏览透视图的设计目标是向您提供各种类型的信息,这些信息是根据一个选择标准的集合进行过滤的。该透视图的行为通过使用一系列的连续视图为您过滤信息。相比之下,Java 透视图是视图、编辑器和动作的集合,它向您提供编辑和编译 Java 代码的能力。该透视图的行为是面向任务的,并且为最终用户提供一个工具集合,以便完成特定的目标。
创建基本的透视图
在创建了插件项目之后,需要创建透视图,创建透视图是一个两阶段的过程。首先,修改插件的清单以包含新的扩展,该扩展将使用 org.eclipse.ui.perspectives 扩展点。其次,使用来自新扩展点的属性创建一个透视图类。根据关于扩展和扩展点的早期讨论,Google 应用程序的插件清单已经包括下列扩展:
...

      
               id="com.ibm.developerworks.google.GooglePerspective"
               name="Google"
               class="com.ibm.developerworks.google.GooglePerspective"/>
...
元素具有下列属性:
id —— 该属性为透视图定义了一个惟一标识符。
name —— 该属性为透视图定义了一个名称,工作台窗口菜单栏将使用它来表示该透视图。
class —— 该属性包含实现 org.eclipse.ui.IPerspectiveFactory 接口的类的完全限定名。
创建基本的透视图(续)
要在 Google 项目内创建透视图类,需要完成下列步骤:
从菜单栏选择 File > New > Class ,以显示 New Java Class 向导。
. New Java Class 向导
在 Name 字段内键入 GooglePerspective
点击 Add 按钮,以显示 Implemented Interfaces Selection 对话框。
在 Choose Interfaces 字段内键入 org.eclipse.ui.IPerspectiveFactory,并点击 OK
点击 Finish 按钮来创建新类。
该向导生成下列源代码:

1       package com.ibm.developerworks.google;
2
3       import org.eclipse.ui.IPageLayout;
4       import org.eclipse.ui.IPerspectiveFactory;
5
6       public class GooglePerspective implements IPerspectiveFactory {
7
8              public void createInitialLayout(IPageLayout layout) {
9
10             }
11      }
第 8 至 10 行中的 createInitialLayout 方法定义了透视图内所有视图和编辑器的初始布局。目前,您暂时不需要修改该方法。但在这个系列的第二部分,一旦定义了透视图,就需要修改该方法。
定义WorkbenchAdvisor和Application类
介绍 WorkbenchAdvisor
前面集中讨论了构成 RCP 应用程序的各种组件。接下来将集中讨论如何将所有的事物结合到一起。在构建 RCP 应用程序时,核心任务之一就是创建一个实现抽象类 org.eclipse.ui.application.WorkbenchAdvisor 的类。WorkbenchAdvisor 类负责配置工作台,当执行 RCP 应用程序时,将显示该工作台。
WorkbenchAdvisor 类包含下列方法,从而为开发人员提供了对普通工作台的生命周期的访问:
initialize —— 应该在显示任何窗口之前首先调用该方法。
preStartup —— 其次执行的就是这个方法,但它的调用是在第一个窗口打开之前。在启动或者恢复期间暂时禁用某些项时,该方法非常有用。
postStartup —— 对该方法的调用是执行的第三个操作,它的调用是在第一个窗口打开之后,可以用该方法重新启用 preStartup 方法中临时禁用的项。
postRestore —— 该方法的调用是在已经根据以前保存的状态重新创建工作台及其窗口之后。
preShutdown ——该方法的调用是在事件循环已经终止,任何窗口尚未关闭之前。
postShutdown ——这是最后一个方法,它在事件循环终止之后被调用。
WorkbenchAdvisor 类包含下列方法,以便为开发人员提供对工作台窗口生命周期的访问:
preWindowOpen —— 在打开每个窗口时调用该方法。
fillActionBars —— 在调用 preWindowOpen 方法之后调用该方法,可以使用它配置窗口的动作栏。
postWindowRestore —— 在根据以前保存的状态重新创建窗口之后调用该方法。
postWindowOpen —— 在已经打开一个窗口之后调用该方法。可以使用该方法注册任何窗口监听器。
preWindowShellClose —— 在用户关闭窗口外壳时调用该方法。
WorkbenchAdvisor 类包含下列方法,以便为开发人员提供对工作台事件循环的访问。
eventLoopException —— 可以调用该方法处理事件循环崩溃的异常。
eventLoopIdle —— 在没有更多的事件需要处理的时候调用该方法。
创建 WorkbenchAdvisor
要创建 WorkbenchAdvisor 类,需要在 PDE 内部完成下列步骤:
从菜单栏选择 File > New > Class,以显示 New Java Class 向导。
在 Name 字段内键入 GoogleWorkbenchAdvisor
点击 Browse 按钮,以显示 Superclass Selection 对话框。
在 Choose a type 字段内键入 org.eclipse.ui.application.WorkbenchAdvisor,并点击 OK
点击 Finish 按钮来创建新类。
该向导生成了下列源代码:

1       package com.ibm.developerworks.google;
2
3       import org.eclipse.ui.application.WorkbenchAdvisor;
4
5
6       public class GoogleWorkbenchAdvisor extends WorkbenchAdvisor {
7
8              public String getInitialWindowPerspectiveId() {
9
10                     return null;
11              }
12       }
在试图于 PDE 内执行 RCP 应用程序之前,需要对该类进行小幅的修改。首先,您需要修改位于第 7 至 9 行中的 getInitialWindowPerspectiveId 方法。该方法应该向新的工作台窗口返回初始透视图的标识符。由于在前面的小节中已经将 Google 透视图定义为 com.ibm.developerworks.GooglePerspective,所以该字符串将被返回给调用函数。其次,您需要添加一个称为 preWindowOpen 的方法。该方法允许您设置工作台的窗口标题和尺寸。已修改的类如下所示:
package com.ibm.developerworks.google;

import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchAdvisor;

public class GoogleWorkbenchAdvisor extends WorkbenchAdvisor {

      public String getInitialWindowPerspectiveId() {
            return "com.ibm.developerworks.google.GooglePerspective";
      }

      public void preWindowOpen(IWorkbenchWindowConfigurer configurer) {
               super.preWindowOpen(configurer);
               configurer.setTitle("Google");
               configurer.setInitialSize(new Point(300, 300));
               configurer.setShowMenuBar(false);
               configurer.setShowStatusLine(false);
               configurer.setShowCoolBar(false);
      }}
创建 Application
在执行应用程序之前,需要创建一个 Application 类。与 Java 类中的 main 方法类似,该类是 RCP 应用程序的主要入口点,正如在插件清单内的 org.eclipse.core.runtime.applications 扩展点之下定义的,它实现了 org.eclipse.core.runtime.IPlatformRunnable 接口。
要创建 Application 类,需要在 PDE 内部完成下列步骤:
从菜单栏选择 File > New > Class,以显示 New Java Class 向导。
在 Name 字段内键入 GoogleApplication
点击 Add 按钮,以显示 Implemented Interfaces Selection 对话框。
在 Choose Interfaces 字段内键入 org.eclipse.core.runtime.IPlatformRunnable,并点击 OK
点击 Finish 按钮来创建新类。
向已生成的类添加下列 run 方法。对于大多数 RCP 应用程序而言,不需要定制该 run 方法,而且可以重新使用该方法。
7.            ...
8.                  public Object run(Object args) throws Exception {
9.                           WorkbenchAdvisor workbenchAdvisor = new GoogleWorkbenchAdvisor();
10.                       Display display = PlatformUI.createDisplay();
11.                       int returnCode = PlatformUI.createAndRunWorkbench(display,
12.                                     workbenchAdvisor);
13.                       if (returnCode == PlatformUI.RETURN_RESTART)
14.                               return IPlatformRunnable.EXIT_RESTART;
15.                       else
16.                               return IPlatformRunnable.EXIT_OK;
17.              }
18.        ...
19.        
利用 PDE 启动应用程序
要在 PDE 内启动应用程序,需要完成下列步骤:
从菜单栏选择 Run > Run... ,以显示 Run 对话框,如图 9 所示。
9. Run 对话框
在 Configurations 字段中突出显示 Run-time Workbench,并点击 New 按钮,以显示新的运行时工作台配置,如图 10 所示:
10. 一个新的运行时工作台配置
在 Name 内段内键入 Google
从 Application Name 字段中选择 Google.googleApplication
点击 Plug-ins 标签,如图 11 所示:
Figure 11. Run 对话框的 Plug-ins 标签
选择单选按钮 Choose plug-ins and fragments to launch from the list
点击 Deselect All 按钮。
选中 Workspace Plug-ins 选项。该操作包含了对 Google 项的选择。
点击 Add Required Plug-ins 按钮。该动作确定了哪些插件是执行应用程序所必需的。当装配单独的应用程序时,将使用该列表。
点击 Apply 按钮。
点击 Run 按钮来执行该应用程序。如果正确进行了所有配置的话,应该显示一个标题为“Google”的窗口,如图 12 所示。尽管该窗口并不执行任何功能,但是它的确向您阐述了如何用 PDE 创建一个普通工作台。
12. 新的 Google 窗口
创建单独的运行程序
导出应用程序
到目前为止,我们已经重点探讨了如何在 Eclipse IDE 内部运行 RCP 应用程序。在本节中,将重点关注如何在 PDE 内部完成下列步骤,从而创建单独的应用程序:
从菜单栏中选择 File > Export... ,以显示Export 对话框,如图 13 所示:
13. Export 对话框
从导出选项的列表中选择 Deployable plug-ins and fragments
点击 Next,以显示 Export 向导的 Export Plug-ins and Fragments 页面,如图 14 所示:
14. Export 向导的 Export Plug-ins and Fragments 页面
选中 Google 插件。
在 Deploy as 字段中选择 a directory structure
点击 Browse 按钮,并选择一个导出位置。
点击 Finish 来构建该项目。
准备目录结构
要完成单独的应用程序,您需要从 Eclipse IDE 目录复制一些文件到 Google 的导出目录。不幸的是,Eclipse 3.0 没有提供将所有需要的相关插件和 JAR 文件复制到导出目录的工具,因此您需要完成下列步骤:
从 Eclipse 3.0 IDE 的根目录将 startup.jar 复制到 Google 应用程序导出目录的根目录中。
从 Eclipse 3.0 IDE 插件目录将下列目录复制到 Google 应用程序导出目录的插件目录中:
org.eclipse.core.expressions_3.0.0
org.eclipse.core.runtime_3.0.0
org.eclipse.help_3.0.0
org.eclipse.jface_3.0.0
org.eclipse.osgi_3.0.0
org.eclipse.swt.win32_3.0.0 (Windows only)
org.eclipse.swt.gtk_3.0.0 (Linux only)
org.eclipse.swt_3.0.0
org.eclipse.ui.workbench_3.0.0
org.eclipse.ui_3.0.0
org.eclipse.update.configurator_3.0.0
测试应用程序
要测试应用程序,则需要创建一个启动脚本。您可以使用自己喜欢的文本编辑器创建一个名为 google.bat(Windows)或者 google.sh(Linux)的文件,该文件包含下列内容:

java -cp startup.jar org.eclipse.core.launcher.Main -application
com.ibm.developerworks.google.googleApplication
                                            
在完成该任务之后,您的导出目录应该具有下列结构:
- google.bat (Windows only)
- google.sh (Linux only)
- startup.jar
+ ----- plugins
        + ----- org.eclipse.core.expressions_3.0.0
        + ----- org.eclipse.core.runtime_3.0.0
        + ----- org.eclipse.help_3.0.0
        + ----- org.eclipse.jface_3.0.0
        + ----- org.eclipse.osgi.services_3.0.0
        + ----- org.eclipse.osgi.util_3.0.0
        + ----- org.eclipse.osgi_3.0.0
        + ----- org.eclipse.swt.win32_3.0.0 (Windows only)
        + ----- org.eclipse.swt.gtk_3.0.0 (Linux only)
        + ----- org.eclipse.swt_3.0.0
        + ----- org.eclipse.ui.workbench_3.0.0
        + ----- org.eclipse.ui_3.0.0
        + ----- org.eclipse.update.configurator_3.0.0
结束语和参考资料
结束语
在开发人员在他们的应用程序中了解和使用 RCP 的同时,RCP 也在不断扩展和演化。尽管我们只开发了示例应用程序,但是相关的源代码和插件清单还是展示了如何构造基本的 RCP 应用程序。本教程提供一个关于 RCP 的概述,本系列的下一部分将探讨普通工作台的内部工作情况,以及 Google RCP 应用程序的开发。
参考资料
下载
本教程中展示的样例 RCP 应用程序的配套源代码包。
从 Eclipse Foundation 下载
Eclipse 3.0

从 Sun Microsystems 下载
Java 2 SDK,Standard Edition 1.4.2

从 Apache Software Foundation 下载
Ant 1.6.1
或者更高版本。
从白皮书 "
Eclipse Technical Overview
"(Eclipse 网站)获取关于 Eclipse 核心组件的介绍。
在 Eclipse 网站,包括
Platform Extension Points
(Eclipse 网站),寻找关于开发插件的更多资源。
developerWorks 上发现关于如何使用标准窗口小部件工具箱和 JFace 的更多资源,其中包括:
将 ActiveX 控件集成到 SWT 应用程序
developerWorks,2003 年 6 月)。
JFace 开发向导
developerWorks,2003 年 5 月)。
将 ActiveX 控件集成到 SWT 应用程序
developerWorks,2003 年 6 月)。
在 developerWorks 上寻找更多关于如何使用 Eclipse 的资源,其中包括:
开发 Eclipse 插件
developerWorks,2002 年 12 月)。
用 Eclipse 进行 XML 开发
developerWorks,2003 年 4 月)。

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
Eclipse 的 Rich Client Platform,第 2 部分:扩展通用工作台
开始之前
关于本教程
本教程是由两部分组成的系列教程的第 2 部分,这篇教程介绍了 Eclipse 的 Rich Client Platform(RCP)。本系列的第 1 部分
Eclipse 的 Rich Client Platform,第 1 部分:入门
一开始回顾了 Eclipse 项目以及 RCP 在市场中的反响。接着讨论了 Eclipse 的插件架构,总结了实现 RCP 应用程序的必要步骤,并提供了一些必要的背景信息。 然后开始用 Eclipse 3.0 IDE 创建一个项目。其中您定义了插件清单,了解了扩展和扩展点,创建了基本的透视图。最后,您用这些组件创建了一些额外的 Java 支持类,启动了一个独立的 RCP 应用程序。
本系列的第 2 部分利用了第 1 部分中讨论的内容,探讨如何用 Eclispe 中其他的用户界面组件,如视图、动作、向导等组装出一个完整的应用程序。在这篇教程中,您将为 Google API 创建一个前端,使之能够查询 Google Web 站点内容众多的目录,并将结果显示出来。这样一个应用程序可以实际说明上述技术的使用方法,使您理解 RCP 平台。
要学习本教程,您应该理解如何使用 Eclipse 3.0,并具备 Java 的实践知识。您不需要具备与 Eclipse 插件开发有关的背景,也不必理解诸如标准部件工具箱(Standard Widget Toolkit,SWT)和 JFace 等技术。
第 1 部分
中简要介绍了上面这些技术。本教程将浏览代码和相关的支持文件,这样您就能掌握 RCP 应用程序的构建方法。
工具
下列工具不是必需的,但是如果下载、安装、配置了这些工具将使您学习本教程的过程更加容易:Eclipse 3.0、JVM 1.4、以及 Apache Ant。如果尚未安装这些工具,请参照下面的资源,下载并安装:
Eclipse 3.0 可从
http://www.eclipse.org/downloads/index.php
获得。
Java 2 Standard Edition,Software Development Kit (SDK) 可从
http://java.sun.com/j2se/1.4.2/download.html
获得。
Apache Ant 1.6.1 可从
http://ant.apache.org/
获得。
关于作者
Jeff Gunther 是
Studio B
的作者,还是 Intalgent Technologies 的总经理和创始人,这是一家新兴的采用 Java 2 企业版和 Lotus Notes/Domino 平台的软件产品和解决方案的提供商。Jeff 是一个应用程序和基础设施架构师,具有架构、设计、开发、部署和维护复杂软件系统方面的经验。他在许多方面都有丰富经验,其中包括运行于多种平台(从 Web 服务器到嵌入式设备)之上的软件的整个生命周期开发。您可以通过
jeff.gunther@intalgent.com
与 Jeff 联系。
定义视图
视图概述
在 Eclipse 工作台中,视图是一些可视化的容器,它允许用户显示或导航特定类型的资源。当您在自己的 RCP 应用程序中创建视图时,请记住,开发之前一定要回顾一下视图的目的。由于视图的职责在于显示您的域模型内的数据,所以应当将相似类型的对象分到同一个视图中。比如说,大多数 Eclispe IDE 的用户都会扩展 Java 透视图中任务视图的使用范围。这个视图显示的数据类型是自动生成的错误、警告或与某种资源有关的信息,开发人员需要通过这些信息分析并解决问题。这种方法使用户完成特定任务时对视图切换的需求降到了最低。任何应用程序包含的视图数量很大程度上依赖于应用程序的规模和复杂程度。本教程中的 Google 应用程序示例有两个视图,一个用于搜索,另一个用于显示搜索结果的 Web 页面,本节中您将创建这两个视图。
定义 org.eclipse.ui.views 扩展
创建新视图的方法与 Eclispe 中的其他组件类似,您必须在项目的插件清单中定义一个新的扩展。可通过 org.eclipse.ui.perspectives 扩展点来定义视图。在 Google 项目插件清单编辑器的 plugin.xml 标签页中,增加下面的内容,开始视图的创建过程:

...
      

                  
                        id="com.ibm.developerworks.google.views"
                        name="Google">
                  

                  
                        id="com.ibm.developerworks.google.views.SearchView"
                        name="Search"
                        category="com.ibm.developerworks.google.views"
                        class="com.ibm.developerworks.google.views.SearchView"
                        icon="icons/google.gif">
                  

                  
                        id="com.ibm.developerworks.google.views.BrowserView"
                        name="Browser"
                        category="com.ibm.developerworks.google.views"
                        class="com.ibm.developerworks.google.views.BrowserView"
                        icon="icons/google.gif">
                  

      
...

SearchView 允许用户搜索 Google 并在一张表中显示搜索结果。BrowserView 中包含一个 SWT 浏览器控件,可根据用户在搜索结果表中的动作显示某个特定的 URL。
接下来,您将详细了解视图扩展中的要素和属性。
逐步了解 org.eclipse.ui.views 扩展点
,,和  元素可用于定义视图扩展点。在 Show View Dialog 视图中通过一个目录将相似的视图分组。每一个视图都可以在多个目录下出现。
具有下列属性:
id -- 这个属性定义了该目录的唯一标识。
name -- 该属性定义了目录的名称,工作台使用这个属性来代表该目录。
parentCategory -- 这个属性是可选的,它定义的是一个由‘/’分隔的目录清单。该元素创建了目录的层次结构。
元素的属性如下:
id -- 这个属性定义了视图的唯一标识。
name -- 这个属性定义了视图的名称,工作台用它代表视图。
category -- 这个属性是可选的,它定义了目录的标识。每一个目录都由‘/’分开,而且在被该  元素引用之前必须存在于插件清单中。
class -- 这个属性中包含实现了 org.eclipse.ui.IViewPart 接口的类的完全限定名。
icon -- 这个属性是可选的,其中包含了与该视图相关的图标的相对名称。
fastViewWidthRatio -- 这个属性是可选的,其中包含了该视图占整个工作台宽度的百分比。这个属性的值必须是介于 0.05 和 0.95 之间的浮点数。
allowMultiple -- 这个属性是可选的,它指示出是否允许在工作台中创建该视图的多个实例。
创建 SearchView
要在 Google 项目中创建 SearchView 类,完成下列步骤即可:
从²?¥8中选择 File > New > Class,显示出 New Java Class 向导。
1. New Java Class 向导
在 Package 字段中输入 com.ibm.developerworks.google.views
在 Name 字段中输入 SearchView
点击 Browse 按钮,显示 Superclass Selection 对话框。
在 Choose a Type 字段中输入 org.eclipse.ui.part.ViewPart,然后点击 OK
点击 Finish 按钮,创建这个新类。
实现 SearchView
待这个类创建好之后,必须实现 createPartControl 和 setFocus 方法。createPartControl 方法负责创建视图的用户界面控制。在这种情况下,可以用 SWT GridLayout 布局在视图中安排 SWT 标题、SWT 文本、SWT 按钮和一个 SWT 表格。有关 SWT 中各种不同布局的详细信息,以及了解如何使用 SWT 用户界面组件,请访问本教程结束部分的
参考资料

createPartControl 方法中的代码负责呈现用户界面,如图 2 所示。
...
    public void createPartControl(Composite parent)
    {
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 3;
        gridLayout.marginHeight = 5;
        gridLayout.marginWidth = 5;
      
        parent.setLayout(gridLayout);
      
        Label searchLabel = new Label(parent, SWT.NONE);
        searchLabel.setText("Search:");
      
        searchText = new Text(parent, SWT.BORDER);
        searchText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
                | GridData.HORIZONTAL_ALIGN_FILL));
      
        Button searchButton = new Button(parent, SWT.PUSH);
        searchButton.setText(" Search ");
...
        GridData gridData = new GridData();
        gridData.verticalAlignment = GridData.FILL;
        gridData.horizontalSpan = 3;
        gridData.grabExcessHorizontalSpace = true;
        gridData.grabExcessVerticalSpace = true;
        gridData.horizontalAlignment = GridData.FILL;
      
        tableViewer = new TableViewer(parent, SWT.FULL_SELECTION | SWT.BORDER);
        tableViewer.setLabelProvider(new SearchViewLabelProvider());
        tableViewer.setContentProvider(new ViewContentProvider());
        tableViewer.setInput(model);
        tableViewer.getControl().setLayoutData(gridData);
        tableViewer.addDoubleClickListener(this);
      
        Table table = tableViewer.getTable();
        table.setHeaderVisible(true);
        table.setLinesVisible(true);
      
        TableColumn titleColumn = new TableColumn(table, SWT.NONE);
        titleColumn.setText("Title");
        titleColumn.setWidth(250);
      
        TableColumn urlColumn = new TableColumn(table, SWT.NONE);
        urlColumn.setText("URL");
        urlColumn.setWidth(200);
...
2. Google 应用程序中的搜索视图
实现 SearchView 类,续上节
除了 createPartControl 方法之外,setFocus 方法也是必须实现的。在这个例子中,缺省的焦点是一个 SWT Text 字段,它允许用户输入在 Google 中搜索的标准。当在工作台中呈现该视图时,就调用这个方法。
...
    public void setFocus()
    {
        searchText.setFocus();
    }
...
一旦用户在搜索结果表中双击某一行,就会在另一个包含 SWT 浏览器控件的视图中加载所选的 Web 站点。这个过程是通过 SearchView 所实现的 IDoubleClickListener 接口完成的。IDoubleClickListener 接口要求在 SearchView 中增加 doubleClick 方法。
...
    public void doubleClick(DoubleClickEvent event)
    {
        if (!tableViewer.getSelection().isEmpty())
        {
      
            IStructuredSelection ss = (IStructuredSelection) tableViewer
                    .getSelection();
            GoogleSearchResultElement element = (GoogleSearchResultElement) ss
                    .getFirstElement();
      
            BrowserView.browser.setUrl(element.getURL());
        }
      
    }
...
下面是 SearchView 类的完整源代码:
package com.ibm.developerworks.google.views;
      
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.internal.dialogs.ViewContentProvider;
import org.eclipse.ui.part.ViewPart;
      
import com.google.soap.search.GoogleSearch;
import com.google.soap.search.GoogleSearchFault;
import com.google.soap.search.GoogleSearchResult;
import com.google.soap.search.GoogleSearchResultElement;
import com.ibm.developerworks.google.GoogleApplication;
      
public class SearchView extends ViewPart implements IDoubleClickListener
{
    public static final String ID = "com.ibm.developerworks.google.views.SearchView";
      
    private TableViewer tableViewer;
      
    private Text searchText;
      
    private GoogleSearchResultElement model;
      
    public void createPartControl(Composite parent)
    {
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 3;
        gridLayout.marginHeight = 5;
        gridLayout.marginWidth = 5;
      
        parent.setLayout(gridLayout);
      
        Label searchLabel = new Label(parent, SWT.NONE);
        searchLabel.setText("Search:");
      
        searchText = new Text(parent, SWT.BORDER);
        searchText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
                | GridData.HORIZONTAL_ALIGN_FILL));
      
        Button searchButton = new Button(parent, SWT.PUSH);
        searchButton.setText(" Search ");
        searchButton.addSelectionListener(new SelectionListener()
        {
      
            public void widgetSelected(SelectionEvent e)
            {
      
                GoogleSearch search = new GoogleSearch();
                search.setKey(GoogleApplication.LICENSE_KEY);
                search.setQueryString(searchText.getText());
                try
                {
                    GoogleSearchResult result = search.doSearch();
      
                    tableViewer.setInput(model);
                    tableViewer.add(result.getResultElements());
      
                } catch (GoogleSearchFault ex)
                {
                    MessageDialog.openWarning(e.display.getActiveShell(),
                            "Google Error", ex.getMessage());
                }
      
            }
      
            public void widgetDefaultSelected(SelectionEvent e)
            
            }
        });
     
        GridData gridData = new GridData();
        gridData.verticalAlignment = GridData.FILL;
        gridData.horizontalSpan = 3;
        gridData.grabExcessHorizontalSpace = true;
        gridData.grabExcessVerticalSpace = true;
        gridData.horizontalAlignment = GridData.FILL;
      
        tableViewer = new TableViewer(parent, SWT.FULL_SELECTION | SWT.BORDER);
        tableViewer.setLabelProvider(new SearchViewLabelProvider());
        tableViewer.setContentProvider(new ViewContentProvider());
        tableViewer.setInput(model);
        tableViewer.getControl().setLayoutData(gridData);
        tableViewer.addDoubleClickListener(this);
      
        Table table = tableViewer.getTable();
        table.setHeaderVisible(true);
        table.setLinesVisible(true);
      
        TableColumn titleColumn = new TableColumn(table, SWT.NONE);
        titleColumn.setText("Title");
        titleColumn.setWidth(250);
      
        TableColumn urlColumn = new TableColumn(table, SWT.NONE);
        urlColumn.setText("URL");
        urlColumn.setWidth(200);
      
    }
      
    public void setFocus()
    {
        searchText.setFocus();
    }
      
    public void doubleClick(DoubleClickEvent event)
    {
        if (!tableViewer.getSelection().isEmpty())
        {
      
            IStructuredSelection ss = (IStructuredSelection) tableViewer
                    .getSelection();
            GoogleSearchResultElement element = (GoogleSearchResultElement) ss
                    .getFirstElement();
      
            BrowserView.browser.setUrl(element.getURL());
        }
      
    }
}
创建 SearchViewLabelProvider
在上一页的源代码中,TableViewer 对象使用了一个名为 SearchViewLabelProvider 的类。本例中,标题提供方为表中的每一行数据设置栏中的文本。要在 Google 项目中为 SearchView 类创建 SearchViewLabelProvider 类,可遵照下面的步骤:
从菜单栏中选择 File > New > Class ,显示 Java Class 向导。
在 Package 字段中输入 com.ibm.developerworks.google.views
在 Name 字段中输入 SearchViewLabelProvider
点击 Browse 按钮,显示 Superclass Selection 对话框。
在 Choose a Type 中输入 org.eclipse.jface.viewers.LabelProvider ,然后点击 OK
点击 Add 按钮,显示 Implemented Interfaces Selection 对话框。
在 Choose an interface 字段中输入 org.eclipse.jface.viewers.ITableLabelProvider ,然后点击 OK
点击 Finish 按钮,创建这个新类。
实现 SearchViewLabelProvider
ITableLabelProvider 接口要求在类中实现 getColumnImage 和 getColumnText 方法。由于显示结果的表格中并不包含图像,因此 getColumnImage 方法只返回空即可。getColumnText 使用 Google API 中提供的 GoogleSearchResultElement 类设置 SWT 表中的第一栏和第二栏。第一栏中包含着搜索结果的标题,第二栏中包含搜索结果的 URL。
package com.ibm.developerworks.google.views;
      
...
      
public class SearchViewLabelProvider extends LabelProvider implements
        ITableLabelProvider
{
      
    public Image getColumnImage(Object element, int columnIndex)
    {
        return null;
    }
      
    public String getColumnText(Object element, int columnIndex)
    {
        switch (columnIndex)
        {
        case 0:
            return ((GoogleSearchResultElement) element).getTitle();
        case 1:
            return ((GoogleSearchResultElement) element).getURL();
      
        }
        return "";
      
    }
      
}
创建 BrowserView
现在,您需要创建一个视图来显示用户在搜索结果表中选中的 URL。要在 Google 项目中创建 BrowserView 类,可遵从下列步骤:
从菜单栏中选择 File > New > Class,显示 New Java Class 向导。
在 Package 字段中输入 com.ibm.developerworks.google.views
在 Name 字段中输入 BrowserView
点击 Browse 按钮,显示 Superclass Selection 对话框。
在 Choose a Type 字段中输入 org.eclipse.ui.part.ViewPart,然后点击 OK
点击 Finish 按钮,创建新类。
实现 BrowserView
BrowserView 类和 SearchView 类的情况一样,您必须实现 createPartControl 和 setFocus 方法。在本例中,视图中嵌入了一个 SWT 浏览器控件。这个控件显示用户在搜索结果表中选中的 Web 页面。
package com.ibm.developerworks.google.views;
      
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
      
public class BrowserView extends ViewPart
{
    public static final String ID = "com.ibm.developerworks.google.views.BrowserView";
      
    public static Browser browser;
      
    public void createPartControl(Composite parent)
    {
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 1;
        gridLayout.marginHeight = 5;
        gridLayout.marginWidth = 5;
        parent.setLayout(gridLayout);
      
        browser = new Browser(parent, SWT.NONE);
      
        browser.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
                | GridData.GRAB_VERTICAL | GridData.FILL_HORIZONTAL
                | GridData.FILL_VERTICAL));
        browser.setUrl("about:");
      
    }
      
    public void setFocus()
    {
        browser.setFocus();
      
    }
}
SearchView BrowserView 集成到一个透视图中
您的 Google 应用程序中定义了上面两个视图以及相关的支撑类,现在需要将这些组件集成到您在第 1 部分中已经创建好的透视图中。打开 GooglePerspective 类,修改其中的 createInitialLayout 方法。
下面是 GooglePerspective 类的完整源代码:
package com.ibm.developerworks.google;
      
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPerspectiveFactory;
      
import com.ibm.developerworks.google.views.BrowserView;
import com.ibm.developerworks.google.views.SearchView;
      
public class GooglePerspective implements IPerspectiveFactory
{
    public static final String ID = "com.ibm.developerworks.google.GooglePerspective";
      
    public void createInitialLayout(IPageLayout layout)
    {
        layout.setEditorAreaVisible(false);
        layout.addView(SearchView.ID, IPageLayout.BOTTOM, new Float(0.60)
                .floatValue(), IPageLayout.ID_EDITOR_AREA);
        layout.addView(BrowserView.ID, IPageLayout.TOP, new Float(0.40)
                .floatValue(), IPageLayout.ID_EDITOR_AREA);
    }
}
如图 3 所示,createInitialLayout 中的最后两行负责在呈现透视图的时候打开 SearchView 和 BrowserView。addView 方法包含四个参数:
第一个参数中包含视图的唯一标识。
第二个参数定义了与工作台的关系。可能的选项包括 Top、Bottom、Left、和 Right。
第三个参数定义了如何在工作台中划分可用空间的比率。这个参数是个浮点数,它的值在 0.05 和 0.95 之间。
最后一个参数中包含了视图显示地点的唯一标识引用。在本例中,使用的是编辑器的区域。
3. Google 应用程序的 Search Browser 视图
下一节着重介绍如何向 RCP 应用程序中增加菜单栏、对话框、动作和向导。
集成菜单栏和对话框
向透视图中增加菜单栏
有时您可能想在主窗口中创建菜单栏,从而向 RCP 中加入某些行为。要向菜单栏中增加新项,您需要在 WorkbenchAdvisor 中覆盖 fillActionBars 方法。

...
    public void fillActionBars(IWorkbenchWindow window,
            IActionBarConfigurer configurer, int flags)
    {
        IMenuManager menuBar = configurer.getMenuManager();
        
        MenuManager fileMenu = new MenuManager("File",
                IWorkbenchActionConstants.M_FILE);
        fileMenu.add(new GroupMarker(IWorkbenchActionConstants.FILE_START));
        fileMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
        fileMenu.add(ActionFactory.QUIT.create(window));
        fileMenu.add(new GroupMarker(IWorkbenchActionConstants.FILE_END));
        
        menuBar.add(fileMenu);        
    }
...

在上面的源代码中,MenuManager 类向工作台中增加了一个 fileMenu。图 4 展示了 Google 应用程序中实际的菜单栏。
4. WorkbenchAdvisor 类中的菜单栏
除了菜单栏之外,JFace 工具箱还提供了一些预定义的对话框,可以增强 RCP 应用程序的用户体验。下一页将回顾 JFace 包提供的各种对话框类型。
各种不同类型的对话框
JFace 工具箱中包含各种不同类型的对话框,可以给应用程序的用户显示信息。如图 5 所示,如果用户没有在执行查询之前给 Google API 提供许可证键值,那么 SearchView 类就会使用 MessageDialog 类给用户显示出错信息。
5. 没有提供许可证键值的情况下显示的出错信息
除了 MessageDialog 之外,JFace 包还提供了三种其他的对话框类型:
ErrorDialog 使用 IStatus 对象,显示有关某个特定错误的信息。
InputDialog 允许用户向对话框中输入文本。
ProgressMonitorDialog 向用户显示某个执行过程。
下一节将介绍如何向 RCP 应用程序中加入向导,以实现数据的收集。
定义向导
向导概述
JFace 工具箱中包含了一组强大的用户界面控件,您很容易就能将其集成到 RCP 应用程序中。这个工具箱中有一个有趣的控件,就是对向导的支持。JFace 向导与 SWT 中的其他用户界面组件一起,提供了一种灵活的机制,可以有条不紊地收集用户的输入信息,并执行输入验证。
在了解创建向导的代码和实现细节之前,让我们先回顾一下向导在 Google 应用程序中的作用。要查询 Google API,就必须用某个帐号登录。一旦帐号被激活,您就可以提供一个许可证键值。目前,Google 允许每一个帐号每天执行 1000 次查询。由于您要在 GoogleSearch 对象中提供许可证键值作为参数,因此需要有一种机制能够从用户那里搜集许可证键值信息。
如图 6 所示,应用程序中包含了一个 JFace 向导,它由一个页面构成,负责请求输入许可证键值。
6. Google 应用程序中的许可证键值向导
有关如何创建帐号访问 Google API 的更多信息,请参阅
参考资料

创建 LicenseKeyWizard
可通过扩展 org.eclipse.jface.wizard.Wizard 创建一个基本的向导。在 Google 应用程序中,向导将用于收集用户的 Google API 许可证键值。在 Google 项目中创建 LicenseKeyWizard 类的完整过程如下:
从菜单栏中选择 File > New > Class,显示 New Java Class 向导。
在 Package 字段中输入 com.ibm.developerworks.google.wizards
在 Name 字段中输入 LicenseKeyWizard
点击 Browse 按钮,显示 Superclass Selection 对话框。
在 Choose a Type 字段中输入 org.eclipse.jface.wizard.Wizard,然后点击 OK
点击 Finish 按钮,创建新类。
实现 LicenseKeyWizard
创建了 LicenseKeyWizard 类之后,您需要覆盖 addPages 和 performFinish 两个方法。addPages 方法负责在向导中增加页面,然后再显示给用户。当用户点击向导中的 Finish 按钮时,执行 performFinish 方法。LicenseKeyWizard 收集许可证键值数据,并在这个类中将键值组装为静态 String 变量。
下面是 LicenseKeyWizard 类的完整代码:

package com.ibm.developerworks.google.wizards;

import org.eclipse.jface.wizard.Wizard;


public class LicenseKeyWizard extends Wizard
{
    private static String licenseKey;
    private LicenseKeyWizardPage page;
   
    public LicenseKeyWizard()
    {
        super();
        this.setWindowTitle("License Key");
    }

    public void addPages()
    {
        page = new LicenseKeyWizardPage("licenseKey");
        addPage(page);
    }
    public boolean performFinish()
    {
        if(page.getLicenseKeyText().getText().equalsIgnoreCase(""))
        {
            page.setErrorMessage("You must provide a license key.");
            page.setPageComplete(false);
            return false;
        }
        else
        {
            licenseKey = page.getLicenseKeyText().getText();
            return true;
        }
        
    }

    public static String getLicenseKey()
    {
        return licenseKey;
    }

    public static void setLicenseKey(String licenseKey)
    {
        LicenseKeyWizard.licenseKey = licenseKey;
    }
}
创建 LicenseKeyWizardPage
除了向导类之外,每一个向导还必须拥有至少一个扩展 org.eclipse.jface.wizard.WizardPage 的页面。要在 Google 项目中创建 LicenseKeyWizardPage 类,可遵从下面的步骤:
从菜单栏中选择 File > New > Class,显示 New Java Class 向导。
在 Package 字段中输入 com.ibm.developerworks.google.wizards
在 Name 字段中输入 LicenseKeyWizardPage
点击 Browse 按钮,显示 Superclass Selection 对话框。
在 Choose a Type 字段中输入 org.eclipse.jface.wizard.WizardPage,然后点击 OK
点击 Finish 按钮,创建新类。
实现 LicenseKeyWizardPage
如果没有类实现 WizardPage,那么 LicenseKeyWizard 就不会有任何行为。您可以将向导看作卡片笺,其中每一张卡片都有自己的布局和设计。每一个 WizardPage 都负责向导中单个页面或卡片的布局与行为。为了创建 WizardPage,您需要实现 WizardPage 基类的子类,并实现 createControl 方法,创建特定的用户界面控件。
LicenseKeyWizardPage 类的完整源代码如下所示:

package com.ibm.developerworks.google.wizards;

import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class LicenseKeyWizardPage extends WizardPage
{
    private Text licenseKeyText;

    protected LicenseKeyWizardPage(String pageName)
    {
        super(pageName);
        setTitle("License Key");
        setDescription("Define your Google API License Key");
    }

    public void createControl(Composite parent)
    {
        GridLayout pageLayout = new GridLayout();
        pageLayout.numColumns = 2;
        parent.setLayout(pageLayout);
        parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        Label label = new Label(parent, SWT.NONE);
        label.setText("License Key:");

        licenseKeyText = new Text(parent, SWT.BORDER);
        licenseKeyText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        
        setControl(parent);
    }

    public Text getLicenseKeyText()
    {
        return licenseKeyText;
    }

    public void setLicenseKeyText(Text licenseKeyText)
    {
        this.licenseKeyText = licenseKeyText;
    }
}
定义动作
动作概述
在 Eclipse 工作台中,动作就是应用程序用户触发的命令。一般来说,动作可分为三种孑然不同的类型:按钮、工具条内部的动作项,以及菜单栏内部的动作项。比如说,当您从菜单栏中选择 File > New > Class 时,您执行的是打开 New Java Class 向导的动作。当您在工作台内部执行动作时,动作的 run 方法会在应用程序中执行其特定的功能。除了动作的类之外,动作还可以具有其他性质,用于在工作台内控制动作的呈现方式。这些性质包括文本标题、鼠标越过时的提示,以及一个图标。本教程所举的 Google 应用程序例子中有两个动作——一个用于退出应用程序,另一个允许用户通过点击位于 Search 视图中的按钮来提供 Google API 许可证键值。
本节将介绍如何在插件清单中用扩展点定义动作。特别要指出如何将动作加入 Search 视图的下列菜单中。
定义 org.eclipse.ui.viewActions 扩展点
要向视图中增加新的动作,您必须在项目的插件清单中定义新的扩展。视图动作是用 org.eclipse.ui.viewActions 定义的。每一个视图都有一个下拉菜单,当点击右上角的三角按钮时,就激活这个菜单。打开 Google 项目插件清单编辑器中的 plugin.xml 标签页,然后在其中加入下列内容,以此开始创建视图动作的过程:

...
      
         
            
                  id="com.ibm.developerworks.google.views.contribution"
                  targetID="com.ibm.developerworks.google.views.SearchView">

                        
                            id="com.ibm.developerworks.google.actions.LicenseKeyAction"
                            label="License Key"
                            toolbarPath="additions"
                            style="push"
                            state="false"
                            tooltip="Google License Key"
           class="com.ibm.developerworks.google.actions.LicenseKeyAction" />

            

      
...

LicenseKey 视图动作允许用户设置查询 Google API 时使用的许可证键值。下面几页将描述 org.eclipse.ui.viewActions 扩展点和创建 Action class 所需的必要步骤。
逐步构建 org.eclipse.ui.viewActions 扩展点
从  元素开始,在一个简单的 org.eclipse.ui.viewActions 扩展中包含  和  元素。
定义了一组视图动作和菜单。这个元素具有下面的属性:
id -- 该属性定义了视图功能(contribution)的唯一标识。
targetID -- 该属性定义了一个已注册的视图,而这个视图正是该功能的目标。
元素具有下面的属性:
id -- 该属性定义了动作的唯一标识。
label -- 该属性定义了该动作的名称,工作台用这个名称代表该动作。
menubarPath -- 该属性是可选的,其中包含用斜线‘/’分隔的路径,用于指定该动作在下列菜单中的位置。
toolbarPath -- 该属性是可选的,其中包含目标视图工具条中的一个命名组。如果忽略该属性,则动作不会出现在视图的工具条中。
icon -- 该属性是可选的,其中包含了用于在视图中代表该动作的图标所在的相对位置。
disableIcon -- 该属性是可选的,其中包含了当动作禁用时在视图中代表该动作的图标的相对位置。
hoverIcon -- 该属性是可选的,其中包含了当鼠标指针越过该动作时用于代表该动作的图标的相对位置。
tooltip -- 该属性是可选的,它定义了动作提示中的文本。
helpContextId -- 该属性是可选的,它定义了指向该动作帮助上下文的唯一标识。
style -- 该属性是可选的,它定义了动作的用户界面风格。选项包括 push、radio 和 toggle。
state -- 该属性是可选的,当 style 属性的值为 toggle 时,这个属性定义的是动作的初始状态。
class -- 该属性包含实现 org.eclipse.ui.IViewActionDelegate 接口的类的完全限定名称。

创建 LicenseKeyAction
要为 SearchView 创建 LicenseKeyAction,可在 Google 项目中执行下面的步骤:
从菜单栏中选择 File > New > Class,显示 New Java Class 向导。
在 Package 字段中输入 com.ibm.developerworks.google.actions
在 Name 字段中输入 LicenseKeyAction
点击 Add 按钮,显示 Implemented Interfaces Selection 对话框。
在 Choose an interface 字段中输入 org.eclipse.ui.IViewActionDelegate,然后点击 OK
点击 Finish 按钮,创建新类。
实现 LicenseKeyAction
当某个动作被激活时,将执行动作的 run 方法。在 Google 应用程序中,LicenseKeyAction 类启动一个向导,收集用户的 Google API 许可证键值。在本例中,这个动作位于搜索视图的右上角。
下面是 LicenseKeyAction 类的源代码:

package com.ibm.developerworks.google.actions;

import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;

import com.ibm.developerworks.google.views.SearchView;
import com.ibm.developerworks.google.wizards.LicenseKeyWizard;

public class LicenseKeyAction implements IViewActionDelegate
{
    private SearchView searchView;

    public void init(IViewPart view)
    {
        this.searchView = (SearchView) view;
    }

    public void run(IAction action)
    {
        LicenseKeyWizard wizard = new LicenseKeyWizard();
        WizardDialog dialog = new WizardDialog(searchView.getViewSite()
                .getShell(), wizard);
        dialog.open();

    }

    public void selectionChanged(IAction action, ISelection selection)
    {

    }

}

在运行 Google 应用程序之前,需要验证项目是否构建成功,以及您是否已经收到使用 Google API 的许可证键值。
启动应用程序
导出应用程序
要创建可以独立运行的 Google 应用程序,可在 Plug-in Development Environment 中执行下面的步骤:
从菜单栏中选择 File > Export,显示 Export 对话框。
7. Export 对话框
从导出选项清单中选择 Deployable plug-ins and fragments
点击 Next,显示 Export 向导的 Export Plug-ins and Fragments 页面。
8. Export 向导的 Export Plug-ins and Fragments 页面
验证 com.ibm.developerworks.google 插件是否选中。
选择 Deploy as 字段下面的 a directory structure
点击 Browse 按钮,选择导出位置。
点击 Finish,构建项目。
准备目录结构
要完成整个独立应用程序,您需要将一些文件从 Eclipse IDE 目录下拷贝到 Google 的导出目录中。不过,Eclipse 3.0 并没有提供一个工具,能够将所有必需依赖的插件和 JAR 文件拷贝到导出目录中。
根据下面的步骤准备目录结构:
从 Eclipse 3.0 IDE 的根目录将 startup.jar 文件拷贝到 Google 应用程序导出目录的根目录。
将下列目录从 Eclipse 3.0 IDE 的 plugin 目录中拷贝到 Google 应用程序导出目录的 plugin 目录中:

org.eclipse.core.expressions_3.0.0
org.eclipse.core.runtime_3.0.0
org.eclipse.help_3.0.0
org.eclipse.jface_3.0.0
org.eclipse.osgi.services_3.0.0
org.eclipse.osgi.util_3.0.0
org.eclipse.osgi_3.0.0
org.eclipse.swt.win32_3.0.0 (Windows only)
org.eclipse.swt.gtk_3.0.0 (Linux only)
org.eclipse.swt_3.0.0
org.eclipse.ui.workbench_3.0.0
org.eclipse.ui_3.0.0
org.eclipse.update.configurator_3.0.0

测试和运行应用程序
当您完成了所有准备目录的任务之后,导出目录中就应该具备下面的结构:

- google.bat (Windows only)
- google.sh (Linux only)
- startup.jar
+ ----- plugins
        + ----- org.eclipse.core.expressions_3.0
        + ----- org.eclipse.core.runtime_3.0.0
        + ----- org.eclipse.help_3.0.0
        + ----- org.eclipse.jface_3.0.0
        + ----- org.eclipse.osgi.services_3.0.0
        + ----- org.eclipse.osgi.util_3.0.0
        + ----- org.eclipse.osgi_3.0.0
        + ----- org.eclipse.swt.win32_3.0.0 (Windows only)
        + ----- org.eclipse.swt.gtk_3.0.0 (Linux only)
        + ----- org.eclipse.swt_3.0.0
        + ----- org.eclipse.ui.workbench_3.0.0
        + ----- org.eclipse.ui_3.0.0
        + ----- org.eclipse.update.configurator_3.0.0

为了测试应用程序,您需要创建一个启动脚本。可以用您喜欢的文本编辑器创建一个名为 google.bat(Windows)或 google.sh(Linux)的文件,其中的内容如下:

java -cp startup.jar org.eclipse.core.launcher.Main
-application com.ibm.developerworks.google.GoogleApplication
                                            
所有的类都创建好了,插件清单也定义完毕,所有必需依赖的库也已就绪,这时您可以启动 Google 应用程序,执行查询了。图 9 说明了如何用 Google API 搜索“eclipse”一词,以及 Eclispe 项目的 Web 站点是如何显示出来的。
9. Google RCP 应用程序及其查询结果
结束语和参考资料
结束语
随着 Eclipse 开发团队开始在开发环境中构建 RCP,我们将看到这个平台激动人心的战略和技术。尽管 RCP 的概念非常新,但是 Eclipse 3.0 版的发布仍然给开发人员提供了一个框架,让他们能够从现在开始使用。本教程中所使用的 Google 应用程序示例说明了工作台的一般用法,介绍了如何将各种不同的用户界面元素集成起来,创建一个一流的跨平台解决方案。
这个系列教程介绍的内容总结如下:
介绍了构成 RCP 应用程序的核心组件,包括透视图、视图、动作和向导。
介绍了如何通过用扩展开发 RCP。
提供了一个 RCP 应用程序示例,您可以用这个程序查询 Google 并显示查询结果。
参考资料
下载
本教程中说明的实例 RCP 应用程序附带的源代码包。
从 Eclipse Foundation 下载
Eclipse 3.0

从 Sun Microsystems 下载
Java 2 SDK, Standard Edition 1.4.2

从 Apache Software Foundation 下载
Ant 1.6.1
或更高版本。
在 Eclipse Web 站点上可以找到更多有关如何使用 SWT 和 JFace 的参考资料,其中包括:
Understanding Layouts in SWT
(Eclipse Web 站点)
Building and delivering a table editor with SWT/JFace
(Eclipse Web 站点)
developerWorks 上可以找到更多有关如何使用 SWT 和 JFace 的资料,其中包括:
Integrate ActiveX controls into SWT applications
developerWorks,2003 年 6 月)
Developing JFace wizards
developerWorks,2003 年 5 月)
developerWorks 上找到更多有关如何使用 Eclispe 的参考资料,其中包括:
Developing Eclipse plug-ins
developerWorks,2002 年 12 月)
XML development with the Eclipse Platform
developerWorks,2003 年 4 月)





本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/20665/showart_230671.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP