Eclipse 相关资料

开发基于eclipse的launch

作者: eclipsetolearn

一、 基本概念
LaunchConfigurations和LaunchConfigurationTypes:LaunchConfigurations表示一个具体的用户launch而LaunchConfigurationTypes表示能生成该类用户launch配置的工具。LaunchConfigurationTypes与LaunchConfigurations的关系有点类似于类与他所对应的对象的关系。用下图来说明:当我们编写一个SWT的应用程序的时候,在launch该程序时,选择SWT Application(对应于LaunchConfigurationTypes),然后生成一个对应于本程序的swt的launch选项New_swt_config(对应于LaunchConfigurations)

说明:
1) LaunchConfigurations必须实现org.eclipse.debug.core.ILaunchConfiguration接口,该接口提供了一些方法用来获取config的配置信息,但不可改变这些配置信息,如果我们想改变这些配置信息,那LaunchConfigurations必须实现org.eclipse.debug.core.ILaunchConfigurationWorkingCopy接口
二、 需要引进的包
如果要使用LaunchConfigurationTypes则需引进org.eclipse.debug.core,如果还有使用UI则需要引进org.eclipse.debug.ui
三、 具体操作步骤
1) 声明一个LaunchConfigurationTypes




说明:
[1]delegate项指定了该LaunchConfigurationTypes所对应的类,该类必须实现org.eclipse.debug.core.model.ILaunchConfigurationDelegate接口的launch()方法。
[2]modes项指定了该LaunchConfigurationTypes所支持的的模式,如果指定为"run, debug",则需要在[1]中的launch方法中判别并分别处理这两种模式。
[3]public指定该LaunchConfigurationTypes是否在UI中出现
2)声明一个LaunchConfigurationTypes的图标




说明;
[1] configTypeID为1)中指定的id
3)在Configuration中声明一个tab group








说明:
[1]class指定的类必须实现org.eclipse.debug.ui.ILaunchConfigurationTabGroup接口
4)实现该tab group
public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
ILaunchConfigurationTab tabs[] = {
new PMainTab(),
new PArgumentsTab(),
new EnvironmentTab(),
new ParallelTab(),
new PDebuggerTab(false),
new PCommonTab(),
new PSelectNodeTab()};
setTabs(tabs);
}
说明:
[1]所有的tab group应当包含org.eclipse.debug.ui.CommonTab这个tab页

5)实现每个tab
说明:
[1]一个tab最重要的方法为下列三个:
public void setDefaults(ILaunchConfigurationWorkingCopy configuration);
public void performApply(ILaunchConfigurationWorkingCopy configuration);
public void initializeFrom(ILaunchConfiguration configuration);
前两个函数把参数从tab拷贝到working copy中,后一个函数把参数从working copy拷贝到tab中,这里从三个函数的参数类型也可体会在第一节中的关于ILaunchConfigurationWorkingCopy和ILaunchConfiguration的概念。
[2] performApply函数示例
public void performApply(ILaunchConfigurationWorkingCopy configuration) {
configuration
.setAttribute(IPTPLaunchConfigurationConstants.MACHINE_NAME,
getMachineName());
configuration.setAttribute(
IPTPLaunchConfigurationConstants.NUMBER_OF_PROCESSES,
getFieldContent(numberOfProcessField));
}
[3] initializeFrom函数示例
public void initializeFrom(ILaunchConfiguration configuration) {
try {
numberOfProcessField.setStringValue(configuration.getAttribute(
IPTPLaunchConfigurationConstants.NUMBER_OF_PROCESSES,
EMPTY_STRING));
int idx = getMachineNameIndex(configuration.getAttribute(IPTPLaunchConfigurationConstants.MACHINE_NAME, EMPTY_STRING));
machineCombo.select(idx);
} catch (CoreException e) {
setErrorMessage(CoreMessages
.getFormattedResourceString(
“CommonTab.common.Exception_occurred_reading_configuration_EXCEPTION”,
e.getStatus().getMessage()));
}

}
[4] isValid函数示例
public boolean isValid(ILaunchConfiguration configuration) {
setErrorMessage(null);
setMessage(null);

if (!numberOfProcessField.isValid()) {
setErrorMessage(numberOfProcessField.getErrorMessage());
return false;
}
return true;
}
如果所有的参数都有合法的值,则返回true
6)实现launch的快捷方式






说明:
[1]class所指定的类必须实现org.eclipse.debug.ui.ILaunchShortcut接口

参考文献:
http://www.eclipse.org/articles/Article-Launch-Framework/launch.html

作者:朱先忠编译

一、 修改Ant Classpath

在使用一个可选的或定制的任务时,你可能需要把其它库添加到classpath中。为此,你可以通过以全局方式或使用一个单独工程的启动配置来修改Ant classpath。为了给一个单独的Eclipse工程设置Ant classpath,打开该工程的Ant启动配置并点击Classpath选择卡;然后,通过点击"Add External JARs"按钮来添加外部的JAR文件。

你可以用全局方式修改Ant classpath以使之应用于所有的工程。为此,你可以选择"Window→Preferences→Ant→Runtime"并点击"Classpath"选项卡。在此,你可以据需要添加JAR文件,通过这种途径进行的设置可以为所有的Ant构建所用。

二、 设置属性值

你可以使用"Ant preferences"页面(通过"Window→Preferences→Ant→Runtime"并点击"Properties"选项卡来打开它)来设置全局的Ant属性。为了添加一个新属性,点击"Add Property"按钮,然后在出现的对话框中填入Name和Value域。这样以来,将为Eclipse中的所有Ant构建设置全局属性;并且由于属性是不可改变的,所以你也就设置了这些属性的最终值。

你可以通过设置工程的Ant启动配置来为每个工程进行属性设置。为此,你可以点击启动配置中的Properties选项卡(见图1),取消选定"Use global properties as specified in the Ant runtime preferences"复选框,并且点击"Add Property"按钮来设置新属性。

图1.设置属性

三、 设置环境变量

你可以设置你想要传递到Ant的环境变量,但是你必须确保Ant会运行在它自己的JRE中(默认情况)。在工程的Ant启动配置中,点击"JRE"选项卡并点击"Separate JRE"单选按钮。为了设置环境变量,点击"Environment"选项卡(显示于图2),并点击"New"按钮来创建一个新的环境变量。

图2.设置环境变量

当你点击"New"按钮时,出现"New Environment Variable"对话框。然后,在适当的域中输入该环境变量的名字和值,并且单击"OK"即可。

四、 配置Ant编辑器

你可以使用Ant编辑器上下文菜单中的"Format"命令(Ctrl-Shift-F)或选择"Edit→Format"命令来重新格式化一个Ant build文件。为此,你可以通过"Window→Preferences→Ant→Editor→Formatter"来打开"Ant preferences"页面,见图3。你所做的任何变化都会反映到该Preview框中。

图3.配置Ant格式

选择"Window→Preferences→Ant→Editor"能够允许你配置build文件编辑器(设置制表位宽度,边界区域,高亮,等等)。
五、 添加新的Ant任务和类型

你可以通过使用"Window→Preferences→Ant→Runtime"中的"Ant preferences"页面来把新的Ant任务和类型添加到Eclipse中。这些任务和类型可以在将来用于build文件而不必使用taskdef或typedef任务(它们在通常情况下是需要的)。

为了添加一项新任务,请选择显示在图4中的"Tasks"选项卡,并点击"Add Task"按钮,然后导航到新的Ant任务所在的JAR文件。为了添加一个新类型,点击"Types"选项卡,并且遵循与刚才一样的步骤即可。

图4.添加Ant任务

提示:如果你不能找到你需要的JAR文件,那么你应该首先把它们添加到Ant classpath中。

作为选择,你可以通过点击Classpath选项卡来把定义任务和类型的其它类添加到Ant classpath中。

六、 使用不同版本的Ant

随同Eclipse一起发行的是Ant 1.6.1,但是也可使用另外其它版本。为此,你可以选择"Window→Preferences→Ant→Runtime"并点击Classpath选项卡从而打开"Ant preferences"页面。

当Eclipse运行Ant时,它在Ant的classpath中查找适当的类-这与在"Ant Home Entries"中设置的一致。为了改变"Ant Home Entries",只要点击"Ant Home"按钮并且选择你希望使用的Ant安装即可。

提示 如果你不想改变classpath,你可以从Eclipse中把Ant作为一个外部的工具运行。为此,你只要选择"Run→External Tools→External Tools"来打开"External Tools"对话框,再点击Program,然后点击New按钮,为这个新工具输入一个名字(例如"Ant 1.8"或其它任何适当的名字)。接下来,转到"Location"域,点击"Browse File System"按钮并且导航到ant.sh或ant.bat(具体依赖于你的操作系统),并且点击"Open"。之后出现"External Tools"对话框;在"Arguments"域中输入你想要传递到Ant的任何参数。最后,在"Working Directory"域中,输入你想要使用的build文件所在的目录并且点击"Run"来启动这个新版本的Ant。这样做所存在的问题是,当在Eclipse中工作时,你不能方便地存取你所拥有的预定义值。总之,在大多数情况中,当构建Eclipse工程时,从Eclipse内使用Ant更好一些。

七、 使用Ant视图

Eclipse的发行中提供了一个Ant视图-它其实是一个窗口(它能够给出在build文件中的目标的概要信息)。为了打开这个视图,选择"Window→Show View→Ant";则该Ant视图即出现在图5的右边。

图5.Ant视图

该视图中的工具栏包含下面按钮(从左到右):

· “Add Build Files”

· “Add Build Files with Search”

· “Hide Internal Targets”

· “Run the Default Target”

· “Remove Selected Build File”

· “Remove All Build Files”

为了把build文件添加到Ant视图,请点击"Add Build Files"按钮以打开"Choose Location"对话框。从该容器的左边,选择你想要使用的Eclipse工程;然后从右边,选择你想要添加到Ant视图的build文件。然后,单击"OK"即可把build文件添加到Ant视图。

提示 在Windows下,你可以通过拖放方式把build文件添加到Ant视图。

除了向你展示一个build文件的概要信息以外,Ant视图还允许你运行build文件。从Ant视图中选择一个build文件并且点击"Run the Default Target"按钮。或右单击一个目标,然后从出现的上下文菜单中选择"Run"。双击Ant视图中的一个build文件将会在Ant编辑器中打开该build文件(这与右单击该build文件并且选择"Open With→Ant Editor"效果一样)。

八、 总结

总之,与Eclipse一起使用Ant是一种非常有潜力的结合。Eclipse允许你开发和调试代码,而Ant让你方便地构建和发布工程。而且,这两个工具都可以自由下载,所以我特别推荐把它们二者联合使用。

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=728632

Eclipse Communication Framework(ECF)是一个新的 Eclipse 项目,目的是提供一个开放源码框架,支持在 Eclipse 平台上创建基于通信的应用程序。本文将研究 ECF、它的基本功能和它未来的方向。
背景

最简单地说,ECF 项目的目的就是提供一个跨协议的 API。ECF 将为四类支持者创造价值:

通信供应者
谁 —— 为基于 Eclipse 的应用程序和插件实现新的和现有的通信供应者(Yahoo、AIM 等)的插件开发人员。
价值 —— 互操作性。开发人员和用户允许他们的应用程序跨协议地协同工作。
组件开发人员
谁 —— 实现通用组件级特性(例如,文件共享或白板共享)的插件开发人员。
价值 —— 可重用性。应用程序设计师现在可以重用组件,只要供应者的实现支持重用。
工具集成人员
谁 —— 把现有应用程序与 ECF 技术进行集成以便增加新价值的插件开发人员。一个好示例就是给图形编辑器添加协同支持。
价值 —— 丰富的特性。开发人员可以通过 ECF 把新东西添加到他们的应用程序中。
用户界面(UI)开发人员
谁 —— 构建或集成用户界面的插件开发人员。ECF 提供了干净的骨架,所以可以为聊天室、文件共享等提供自己的用户界面。
价值 —— 可用性。可以独立于底层实现,在设计甚至集成方面改进用户界面或定制用户界面。
ECF 为了满足这个目标提供了一套高级抽象,而不是另一套消息 API。这一设计选择使得可以在不同的应用程序上下文环境和用户界面中重用高级通信组件(即时消息、文件共享、视频会议等)。假设要开发一个应用程序,需要即时通信、博客、BT 下载、文件共享和语音会议。那么使用 ECF 开发可以跨越每个服务的通信代码,从而让开发人员可以专注于业务逻辑和用户界面。

简介 本文介绍如何在Eclipse中使用Ruby开发工具(RDT)插件进行Ruby开发。本文将有益于那些想学习如何使用Eclipse基础架构来进行Ruby开发的Ruby开发者,也有益于对Ruby开发感兴趣的Java开发者。

一、 为什么使用Ruby?

现在,为什么众多的Java开发者都关注Ruby?Ruby,是10年以前在日本创建的一种通用目的脚本语言,这是一种纯面向对象的语言。不同于Java技术,Ruby中的一切都是对象。Ruby的语法主要来源于Smalltalk,Python和Ada。象Java编程语言一样,Ruby是一种单继承的语言,但是它提供了一些Java技术所没有实现的高级特征,例如闭合(可以认为是一种匿名的内部类)和mix-in(类似于接口,但是较松地绑定于类上)。Ruby也是高度可移植的,能够运行在所有主流的操作系统之上。

现在,Ruby正十分热门。人们正在开始把它应用于各种类型的应用程序。因为它是解释型并且使用动态类型化,所以你可以在运行时刻实现在Java中很难实现的技巧。由动态类型化和富于表达的语法所实现的令人吃惊的能力之一是它能够用Ruby创建域特定的语言(DSL)-它们允许你在更高级别的抽象层上工作,从而远离最原始的语言语法。Ruby on Rails是一种创建基于数据库支持的Web应用程序的框架,这也展示了Ruby的力量。Rake,作为Ruby的Make和Ant合二为一的版本,是这种语言强有力的应用的又一个证明。

使用Ruby的另一个原因是,所有的编程发烧友都在使用它。现在,许多Java高手(如Glenn Vanderburg,Bruce Tate和Martin Fowler)都在使用Ruby。即使你不打算把你的所有开发转向Ruby,这种语言也值得你浏览一番。

限制Ruby发展的主要因素之一是,它缺乏一个良好的开发环境(对于那些不想学习Emacs的用户来说)。如今,RDT改变了这一切,而使用Eclipse对此进行试验则最好不过。

二、 安装

在使用Ruby之前,你必须安装Ruby解释器,相应的库和Ruby开发环境。

三、 取得Ruby

Ruby可用于所有主要的平台上。事实上,你的Linux或Cygwin分发包中可能已经包含了它。请打开一个命令提示符,然后输入"Ruby-v"。
如果你得到一个版本号,那么你已经准备好。否则,你需要检查你所选择的平台的分发包。

如果你正在运行Windows,则选择更容易。RubyForge,作为SourceForge上的Ruby特定的等价物,有一个工程称为One-Click Ruby Installer,这个程序用于在Windows平台上搭建Ruby环境。它还包括另外一些工具,如一个称为FreeRide的IDE;但是如果你使用RDT的话,你在安装过程中可以跳过这些这项。

四、 取得文档

当你开始使用一种新语言时,文档及有关参考材料是至关重要的。你可以在主Ruby网站得到Ruby文档的在线参考材料,但是你会发现这些文档有点过时(它们是针对于Ruby 1.6版本的,而当前版本是1.8.2)。问题是,更新的文档目前还没有从日语翻译过来。然而,你可以在Ruby-doc.org上找到最新的帮助文档。它包括API级的文档(Javadoc的等价物),还有其它一些教程和书籍。

如果你是一位严肃的Ruby开发者,那么你应该阅读一下《Programming Ruby:The Pragmatic Programmer’s Guide》(作者是Dave Thomas和Andy Hunt)一书以取得最佳编程效果。这是一本有关Ruby及Ruby库编程的经典指南。如果你得到此书,那么你还可以参考也是Dave Thomas编写的《Agile Development with Ruby on Rails》一书。这是一本有关Ruby on Rails的入门性书籍。

简介 本文介绍如何在Eclipse中使用Ruby开发工具(RDT)插件进行Ruby开发。本文将有益于那些想学习如何使用Eclipse基础架构来进行Ruby开发的Ruby开发者,也有益于对Ruby开发感兴趣的Java开发者。

一、 为什么使用Ruby?

现在,为什么众多的Java开发者都关注Ruby?Ruby,是10年以前在日本创建的一种通用目的脚本语言,这是一种纯面向对象的语言。不同于Java技术,Ruby中的一切都是对象。Ruby的语法主要来源于Smalltalk,Python和Ada。象Java编程语言一样,Ruby是一种单继承的语言,但是它提供了一些Java技术所没有实现的高级特征,例如闭合(可以认为是一种匿名的内部类)和mix-in(类似于接口,但是较松地绑定于类上)。Ruby也是高度可移植的,能够运行在所有主流的操作系统之上。

现在,Ruby正十分热门。人们正在开始把它应用于各种类型的应用程序。因为它是解释型并且使用动态类型化,所以你可以在运行时刻实现在Java中很难实现的技巧。由动态类型化和富于表达的语法所实现的令人吃惊的能力之一是它能够用Ruby创建域特定的语言(DSL)-它们允许你在更高级别的抽象层上工作,从而远离最原始的语言语法。Ruby on Rails是一种创建基于数据库支持的Web应用程序的框架,这也展示了Ruby的力量。Rake,作为Ruby的Make和Ant合二为一的版本,是这种语言强有力的应用的又一个证明。

使用Ruby的另一个原因是,所有的编程发烧友都在使用它。现在,许多Java高手(如Glenn Vanderburg,Bruce Tate和Martin Fowler)都在使用Ruby。即使你不打算把你的所有开发转向Ruby,这种语言也值得你浏览一番。

限制Ruby发展的主要因素之一是,它缺乏一个良好的开发环境(对于那些不想学习Emacs的用户来说)。如今,RDT改变了这一切,而使用Eclipse对此进行试验则最好不过。

二、 安装

在使用Ruby之前,你必须安装Ruby解释器,相应的库和Ruby开发环境。

三、 取得Ruby

Ruby可用于所有主要的平台上。事实上,你的Linux或Cygwin分发包中可能已经包含了它。请打开一个命令提示符,然后输入"Ruby-v"。
如果你得到一个版本号,那么你已经准备好。否则,你需要检查你所选择的平台的分发包。

如果你正在运行Windows,则选择更容易。RubyForge,作为SourceForge上的Ruby特定的等价物,有一个工程称为One-Click Ruby Installer,这个程序用于在Windows平台上搭建Ruby环境。它还包括另外一些工具,如一个称为FreeRide的IDE;但是如果你使用RDT的话,你在安装过程中可以跳过这些这项。

四、 取得文档

当你开始使用一种新语言时,文档及有关参考材料是至关重要的。你可以在主Ruby网站得到Ruby文档的在线参考材料,但是你会发现这些文档有点过时(它们是针对于Ruby 1.6版本的,而当前版本是1.8.2)。问题是,更新的文档目前还没有从日语翻译过来。然而,你可以在Ruby-doc.org上找到最新的帮助文档。它包括API级的文档(Javadoc的等价物),还有其它一些教程和书籍。

如果你是一位严肃的Ruby开发者,那么你应该阅读一下《Programming Ruby:The Pragmatic Programmer’s Guide》(作者是Dave Thomas和Andy Hunt)一书以取得最佳编程效果。这是一本有关Ruby及Ruby库编程的经典指南。如果你得到此书,那么你还可以参考也是Dave Thomas编写的《Agile Development with Ruby on Rails》一书。这是一本有关Ruby on Rails的入门性书籍。

七、 运行与调试

IDE的特色之一是在同一个环境下运行和调试你构建的应用程序。RDT能够启用这两项功能。

八、 指定一个解释器

这一任务的实现位于Ruby上部和"Installed Interpreters"入口的"Windows>Preferences"对话框中。
Ruby是一种解释性的语言,因此,在RDT能够运行或调试你的应用程序之前,你必须把一个解释器与你的环境关联。这种关联位于Ruby顶部的"Windows>Preferences"对话框中的"Installed Interpreters"入口处。

图8.把一个Ruby解释器与环境相关联

对于你正在使用的Ruby版本,你要把"Location"文本域指向bin目录,之后由RDT来选取所有其它所需要的信息。一旦你关联了解释器,那么你就为运行应用程序作好了准备。

九、 运行Ruby应用程序

运行一个Ruby应用程序实际上类似于运行一个Java应用程序。你可以使用Run菜单来创建一个Run配置,见下图9。

图9.在RDT中建立一个Run配置

当你运行应用程序时,RDT将把控制切换到Ruby解释器,然后在Eclipse工作区底部的控制台窗口内运行应用程序,见下图10。

图10.在RDT内运行一个Ruby应用程序

这个实例显示了运行一个控制台应用程序,但是运行其它类型的应用程序(如GUI程序)的方式与此相同。

十、 用RDT调试

一个IDE要求实现的最关键的特征之一是有效地调试你的应用程序的能力。Ruby解释器包括一个命令行调试器,但是,在如今的图形工具时代有谁会使用一个命令行调试器?幸好,Ruby解释器还通过一特定(可配置)端口来广播其调试信息,而就象RDT这样的工具能够听取该端口并且提供开发者们期望的调试支持类型。

为了在RDT中调试一个Ruby应用程序,我们要象上面创建的Run配置一样创建一个Debug配置。然后,你可以通过点击左边的沟槽设置一个断点并使用调试器来启动应用程序。就象在Java技术中一样,IDE将询问你,是否你想要切换到调试视图下。如果你愿意,则你将看见类似下面图11所示的内容:

图11.在RDT中调试Ruby应用程序

RDT中支持与Java技术调试相同的调试级别。左上边的格子显示出当前执行的线程,右上面的格子显示出变量的值。就象在Java编程语言中一样,你可以进一步分析对象以观看它们内在的成员变量值。屑渥蟊叩母褡酉允镜鼻罢诵械挠τ贸绦虻脑创耄屑溆冶叩母褡酉允綩utline视图-它在这里担当编辑器的作用,允许你通过点按一个标识符来进行导航。Debug窗口的底部显示出Ruby解释器在端口1098上广播的调试信息,而由RDT在该端口上听取调试信息。

调试器支持是RDT的特色。就算你有一个具有优秀的Ruby支持的编辑器,你仍然必须依靠命令行调试器来调试你的应用程序。拥有一个具有全面功能的调试器将会大大提高软件的生产效率。

十一、 测试

作为Java开发者最难实现的Ruby特征之一是动态类型化。如果你习惯于一种强类型化语言,那么动态类型化看上去似乎有点混乱。DT允许各种高级元编程技巧-这在一种强类型化语言中是很难或不可能实现的。当然,你可以放弃编译时刻类型检查的安全设置。那么,是否有一个方法能够实现两种世界的最佳结合呢?

单元测试应该是每一种语言必须实现的,但是它在动态语言中特别关键。单元测试比编译揭示了更多的内容。事实上,你应该改变在单元测试和编译之间的关系上的观点。最近,一位高级软件开发专家认为,“在今后的五年内,我们会把编译作为单元测试的一种弱的实现形式”。单元测试能够提供证实(verification)-编码将如期实现,而不是仅仅进行你输入内容的语法检查。

考虑到单元测试在Ruby世界中的极端重要性,你一定会希望RDT能够使得单元测试易于运行。的确如此!单元测试被包括在Ruby内,因此你不必下载任何其它的扩展。Ruby库中包括了一个TestCase类和一个TestSuite的概念。你可以象创建任何另外的Ruby类一样来创建你的单元测试,从Test::Unit::TestCase中子类化你的测试。列表1是一个Employee类的实例。

列表1.Employee类

class Employee
def initialize(name, salary, hire_year)
@name = name
@salary = salary
@hire_year = hire_year
end
attr_reader :name, :salary, :hire_year
def raise_salary_by(perc)
@salary += (@salary * (perc * 0.01))
end
def to_s
"Name is #{@name}, salary is #{@salary}, " + “hire year is #{@hire_year}”
end
end

相应的单元测试如下:

列表2.相应于Employee类的单元测试

require ‘test/unit/testcase’
require ‘test/unit/autorunner’
require ‘hr’
class TestEmployee < Test::Unit::TestCase
@@Test_Salary = 2500
def setup
@emp = Employee.new(“Homer”, @@Test_Salary, 2003)
end
def test_raise_salary
@emp.raise_salary_by(10)
expected = (@@Test_Salary * 0.10) + @@Test_Salary
assert( expected == @emp.salary)
end
end

为了运行这个单元测试,你可以为该单元测试类创建一个Run配置-作为一个Test::Unit类型,见图12。

图12.RDT包括一个Test::Unit Run配置

当你运行这个测试时,你会得到与Java单元测试相同的支持元素,包括在左下角的类JUnit格子。

图13.运行于IDE中的一个单元测试的例子

你还可以在Ruby中创建TestSuites。TestSuites是Ruby类,它定义一个返回TestSuite的suite方法。这个TestSuite由自动地在每个TestCases中定义的suite组成。列表3是针对几个类的一个示例TestSuite。

列表3.一些类的示例TestSuite

require ‘test/unit/testsuite’
require ‘test/unit/ui/tk/testrunner’
require ‘test/unit/ui/console/testrunner’
require ‘TestEmployee’
require ‘TestManager’
class TestSuite_AllTests
def self.suite
suite = Test::Unit::TestSuite.new(“HR Tests”)
suite << TestEmployee.suite
suite << TestManager.suite
return suite
end
end
#Test::Unit::UI::Tk::TestRunner.run(TestSuite_AllTests)
Test::Unit::UI::Console::TestRunner.run(TestSuite_AllTests)

不同于前面运行单个TestCase的实例,这里的suite作为一独立的应用程序运行。Ruby有两个方法可以显示TestSuite的结果。第一个是"Console Test Runner"-它在控制台输出它的结果。第二个是"Tk TestRunner",它创建一个熟悉的对话框来显示测试的结果。图14显示了一个Tk TestSuite对话框。

图14.图形式的TestSuite对话框

十二、 新版本中的改进

RDT的当前版本是0.50。目前,其开发者正在开发0.60版本。下一个版本中将改进的方面包括:

· 代码折叠功能-提供针对类和方法的代码折叠功能。

· Outline视图-提供更详细的信息,包括对局部变量的支持。

· RI视图-从一个RDT视图中使用Ruby的ri工具。

· 任务标签-以Ruby注释形式为可配置的关键字(如TODO,FIXME)创建任务。

· 编辑器方面的改进-自动添加大括号,圆括号和单/双引号;还有更好的代码助手。

· 检查器快捷方式-在一个调试会话期间,针对经常使用的检查器提供可配置的快捷方式,如显示一个对象的所有方法,全局常量,等等。

接下来的版本将更好地使用JRuby字节码编译器。JRuby是一项工程,它允许把Ruby代码编译为Java字节码。这意味着,RDT的以后版本将更容易地加入到Eclipse世界中,甚至提供更好的支持。

十三、 总结

Ruby最终为业界人士所广泛认可和应用。其中,部分原因应该归功于Ruby on Rails工程的成功的驱动。如今,已经到了考虑如何把Ruby加入到你的"竞争工具箱"中的时候了。当然,RDT也是吸引你加入这一领域的一个重要因素。

学习如何将独立的、基于 Swing 的编辑器作为插件集成到 Eclipse Platform 中。通过使用一些简单的技术,您就可以在 Swing 工具、Eclipse Platform 和各种 SWT 小窗口(widget)之间共享资源,而且这些资源可以通过相互知晓性(mutual awareness)通信。工具供应商如果打算将基于 Eclipse 的开发工具引入市场,又想最低限度地重新编码,也将发现本文有所帮助。
引言

Eclipse Platform 为工具开发提供一组健壮的服务和 API。它使来自完全不同的供应商的工具之间的集成变得平滑,为不同类型的开发工作创建了一个无缝的环境。

Eclipse Platform 的软件组件之一就是 SWT。尽管 SWT 不是 Platform 的一个核心组件集,但它还是不可或缺的,因为它为产品和插件开发者提供了一组基于 Java 的 GUI 小窗口。SWT 与操作系统无关且非常方便,然而它的底层 JNI 接口将展现本机平台的外观和感觉(look-and-feel)以及性能。

总体上讲,对于那些想要编写在 Platform 的各种框架中运行良好且视觉上有吸引力的插件的开发者和供应商来说,SWT 提供了一个优秀的解决方案。然而,SWT 与 Java 的 Swing GUI 小窗口之间的互操作性程度相当低,这一点对 SWT 影响很大。例如,Swing 和 SWT 使用完全不同的事件处理机制。这个差异常常会使由 Swing 和 SWT 共同组成的 GUI 不可用。

为了在 Swing 和 SWT 之间提供一个接口以便提供可接受级别的兼容性,我们已经做了一些工作,比如使开发者能够将 Swing 小窗口嵌入到 SWT 中的 org.eclipse.swt.internal.swt.win32.SWT_AWT 实用程序类。但是,这些方法仍然是实验性的,尚未获得官方支持 — 由此包名内含有“internal”。

这个拙劣的互操作性对于 Eclipse 项目和工具供应商来说,都是令人遗憾的障碍。目前,大量软件开发和测试工具提供用 Swing 编写的用户界面。将一个带有复杂的 Swing GUI 的现有工具移植到 SWT 需要来自供应商的相当多的时间和投资。尽管 Eclipse Platform 具有了所有先天的优势,但是 Swing 和 SWT 之间拙劣的互操作性导致开发成果不那么吸引人。

本文向您说明了如何实现下列操作:

启动一个基于 Swing 的编辑器以编辑 Eclipse Platform Workbench 中任何名为“ThirdParty.java”的 Java 文件
将 Swing 编辑器中所作的源代码更改带回到 Workbench 中
使用 Preference Page 框架控制 Swing 编辑器的属性
使 Swing 编辑器成为“Workbench 知晓的”
从 Swing 编辑器中启动一个 SWT 小窗口
本文引入了一些简单的技术来实现上述操作,无需使用任何不被支持的 API。我们不引用任何内部类并且遵守所有通用的插件规则。为了最有效地使用这些技术,您应该具有编写插件和使用插件开发环境(Plug-in Development Environment)的基本知识,您还应该具有对基于 Swing 的编辑器的源代码的访问权。

假定的 Swing 编辑器:Ed

为了模拟真实的各种工具集成的情况,我们来使用一个假定的基于 Swing 的编辑器(名为“Ed”)。下面是 Ed 的一些特征:

Ed 是基于 Swing 的编辑器。
Ed 继承了 JFrame。
Ed 只处理具有特定名称 ThirdParty.java 的 Java 文件上。
Ed 用一个 JEditorPane和一个 JButton作为私有域。JEditorPane 显示 ThirdParty.java 的所有源代码。 JButton保存源代码。
Ed 是带有一个 main() 方法的独立的 Java 应用程序。
Ed 被设计为在命令提示符下运行。它并不知晓 Eclipse Platform Workbench。

基本概念

由于 Swing 和 SWT 互操作性的限制,难以获得这二者之间的直接通信(如事件处理)。在既不使用不被支持的 API 也不服从任何插件开发规则的情况下,实现这个目的的一条途径就是避免它们彼此嵌入,取而代之的是让它们拥有独立的 Frame。插件类(或者说 Singleton 实用程序类)将处理它们之间的通信,如 图 1所示。例如,Ed 上的 JButton 可以使一个 SWT Shell 出现,显示已编辑的 ThirdParty.java 的一些特定于 Workbench 的属性(如 Project References)。

图 1. Singleton 实用程序类

编辑器集成

集成的主要目的是开发一个用 Ed 作为在 Workbench 中找到的任何 ThirdParty.java 的缺省编辑器的插件。

准备插件项目

在 Workbench 中,创建一个新的插件项目“org.eclipse.jumpstart.editorintegration”,然后选择 Create plug-in project 向导中的“Create plug-in using a template wizard”选项。单击 Next。选中“Add default instance acces”选项,然后单击 Finish。Workbench 切换到 Plug-in Development Perspective。一个空白的插件清单(manifest)文件以及继承了 AbstractUIPlugin 的插件类 EditorintegrationPlugin 是被自动创建的。还生成了插件类的一个私有静态实例以及 getter 方法。

插件清单文件编辑器应该是打开的;如果没打开,双击 plugin.xml 启动它。

该插件需要下面这些库。将它们添加到插件项目的 Java Build Path 下:

ECLIPSE_HOME/plugins/org.eclipse.core.resources/resources.jar
ECLIPSE_HOME/plugins/org.eclipse.jdt.core/jdtcore.jar
ECLIPSE_HOME/plugins/org.eclipse.jdt.ui/jdt.jar
ECLIPSE_HOME/plugins/org.eclipse.swt/swt.jar
ECLIPSE_HOME/plugins/org.eclipse.ui/workbench.jar
插件清单文件

因为这个插件只处理名为 ThirdParty.java 的 Java 文件,所以我们需要为这些 Java 文件指定一个编辑器。在插件清单文件编辑器中,切换到 Extensions 选项卡,然后添加扩展点“Internal and External Editors”。将 default 设为“true”,将 name 设为“Ed - Swing Editor”,将 filenames 设为“ThirdParty.java”,将 launcher 设为“org.eclipse.jumpstart.editorintegration.EdLauncher”。添加的扩展点的源代码看上去应该如清单 1 所示:

清单 1. 添加一个扩展点

Ed 现在是所有 ThirdParty.java 文件的缺省编辑器,如 图 2所示。

图 2. Ed 是所有 ThirdParty.java 文件的缺省编辑器

请注意:一定要包括 icons/thirdparty.gif 文件,它被作为“Open With”菜单中所有 ThirdParty.java 文件的缺省编辑器显示。

集成 Ed 源代码

将 Ed 的源代码导入到插件项目中。如何调用 Ed 由您决定。插件类可以包含一个 Ed 私有域以及一个相应的公有 getter 方法:

清单 2. Ed 作为私有域

private Ed ed = null;

public Ed getEd()
{
if (ed == null)
{
ed = new Ed ();
}
return ed;
}

另外,插件类可以为每个已启动的 ThirdParty.java 文件返回 Ed 的一个单独的实例。您在该插件维护和提供的 Singleton 实用程序类中实现这两种方式中的哪一种都可以。

编辑器启动程序(launcher)

因为插件使用扩展点 org.eclipse.ui.editors ,所以它必须为 Eclipse Platform 提供一个清单文件中指定的编辑器启动程序类。

创建类 org.eclipse.jumpstart.editorintegration.EdLauncher 以实现接口 IEditorLauncher(如果没找到这个接口,请确保 workbench.jar 文件包含在 Project Path 中;请参阅 准备插件项目)。请一定要选中 Wizard 中的“Inherited abstract methods”选项。

每次双击 ThirdParty.java 文件时,Eclipse Platform 都执行 EdLauncher.open(IFile) 来调用该文件类型的缺省编辑器。Platform 将单击的构件作为 IFile 传送给方法。在这种情况下,IFile 是一个 Java 源文件,因此您可以将它因此您可以将它强制转型为 ICompilationUnit。

由于 Ed 并不是为了处理 JDT 对象而设计的,所以您必须从 ICompilationUnit 中抽取源代码内容并将它放到 Ed 中以便查看:

EditorintegrationPlugin.getDefault().getEd().getEditorPane().setText
(ICompilationUnit.getSource());

EditorintegrationPlugin.getDefault().getEd().show();

一旦执行了 show() 方法,Ed 就被作为主 Workbench 窗口外部的一个 JFrame 显示(请参见 图 3)。插件记录已编辑的 ThirdParty.java 的项目名称和包名称。当您试图保存 Ed 中所作的更改时,该信息是至关重要的。

图 3. Swing 编辑器显示在 Workbench 外面

回页首

双向传递(round-tripping):将源代码的更改返回到 Workbench 中

传统的编辑器将在平面文件、二进制资源库中保存源代码,或者将源代码保存到源代码控制系统中。作为一个编辑器,Ed 需要一些方法来保存它显示的对源代码的更改。

Ed 有一个“Save”按钮( JButton),如 Swing 编辑器:Ed 中所描述。按下按钮后, actionPerformed() 方法被调用,Save 按钮触发一个事件。实现一个事件侦听器的对象接收事件并执行源代码保存操作。

您可以用 Singleton 实用程序类(请参阅 编辑器启动程序)作为实现事件侦听器的对象。实用程序类一接收到来自 Save 按钮的事件对象,就从 Ed 中抽取源代码,然后将源代码放入对应的 Workbench 对象中。保存到文件系统的实际工作被委托给 Eclipse Platform。

多个文件在 Workbench 中可能拥有相同的名称。这就是 ThirdParty.java 的项目名称和包名称有用的地方。该信息由插件存储。确切的实现方式由您决定。假定编辑器存储信息,您可以在实用程序类中使用下列代码片段(snippet):

清单 3. 管理文件名称

public void saveButtonPressed() {
try {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();

IProject myProj = root.getProject(getEd().getProjectname());

IFolder myFolder = myProj.getFolder(getEd().getPackageName());

IJavaElement myPackageFragment = JavaCore.create(myFolder);

if (myPackageFragment != null) {
IPackageFragment packageFrag = (IPackageFragment)myPackageFragment;

String sourceFromEd = getEd().getJEditorPane1().getText();

ICompilationUnit icu = packageFrag.getCompilationUnit(“ThirdParty.java”);

icu.getBuffer().setContents(sourceFromValidator);

icu.save(null, true);
}
else {
System.out.println(“myPackageFragment is null.”);
}
} catch (Exception e) {
e.printStackTrace();
}
}

逆向进行双向传递

清单 3 处理“正向”双向传递。还需要“反向”双向传递来把用 Eclipse Platform 的 JDT Java 编辑器在 ThirdParty.java 中所作的任何更改带回到 Ed。

实用程序类可以实现接口 org.eclipse.jdt.core.IElementChangedListener ,您可以用这个接口跟踪对任何 IElements(包括 ICompilationUnit)作的更改。当源代码更改被引入到 Workbench 中的 Java 文件内时,调用方法 elementChanged(ElementChangedEvent) 。

您需要有选择地过滤出那些不涉及 Ed 插件的 IElement 更改。一种过滤方式是从 IElementChangedEvent 参数中抽取 IJavaElementDelta 对象并对其进行检查。例如,下面的语句过滤 Ed 插件情况下不相关的源代码更改。

清单 4. 过滤不相关的源代码更改

IJavaElementDelta delta = event.getDelta();

if (delta != null) {
if(delta.getElement().getElementName().equalsIgnoreCase(“ThirdParty.java”)) {
//code to update Ed’s editor panel.
}
}

对于非 Java 构件的编辑器,IElementChangedListener 不能捕获在 Workbench 中所作的更改。Eclipse Platform 提供接口 org.eclipse.core.resources.IResourceChangeListener 来处理对非 Java 资源所作的更改。

回页首

首选项页面

要为用户提供丰富的、易于使用的功能,工具应该提供可以通过启动参数访问的、或者可以通过 GUI(它不是编辑器的核心图形界面的一部分)访问的可配置的选项。在用于 Eclipse Platform 的插件的情况中,强烈推荐通过 Platform 的 Preference Page 框架(Window -> Preferences)对这些选项进行配置。

为了举例起见,我们将 Ed 的颜色作为一个使用 Platform 首选项页面的可配置的选项来控制。

在插件清单文件中添加一个首选项页面扩展点

在 Eclipse Platform 中,首选项页面被定义为一个扩展点。要使用它,请将它添加到插件清单文件编辑器中,或者将下列代码放入 plugin.xml 中:

清单 5. 将首选项页面添加到 plugin.xml


<page
name=“Swing Editor Preference Page”
class=“org.eclipse.jumpstart.editorintegration.EdPreferencePage1”
id=“Swing Editor Preference Page”

首选项页面类

首选项页面继承了 org.eclipse.jface.preference.PreferencePage 。在这个示例中,简单的首选项页面由三个最大值为 255 的滑动条(slider bar)组成,表示 Ed 的 java.awt.Color 对象的颜色(红、绿和蓝)。

在插件项目中创建清单文件中指定的类 org.eclipse.jumpstart.editorintegration.EdPreferencePage1 。这个类必须继承 org.eclipse.jface.preference.PreferencePage 并实现接口 org.eclipse.ui.IWorkbenchPreferencePage 。

首选项页面呈现出与编辑器启动程序类似的编码问题:JFace/SWT 将如何与 Swing 通信?幸运的是,同样的方式适用。例如, performApply() 方法可能看上去像这样:

清单 6. performApply() 方法

protected void performApply() {
int red = redSWTSlider.getSelection();
int green = greenSWTSlider.getSelection();
int blue = blueSWTSlider.getSelection();

java.awt.Color newColor = new java.awt.Color(red, green, blue);
EditorintegrationPlugin.getDefault().getEd().getContentPane().setBackground(
newColor);
}

插件应该使用 Platform 的 Preference Store 机制存储已配置的值,任何其他的插件也应该这么做。 performOk() 方法可能看上去像这样:

清单 7. performOk() 方法

public boolean performOk() {
getPreferenceStore().setValue(“redValue”, redSWTSlider.getSelection();
getPreferenceStore().setValue(“greenValue”, greenSWTSlider.getSelection());
getPreferenceStore().setValue(“blueValue”, blueSWTSlider.getSelection());
return true;
}

图 4中显示了从首选项页面控制 Swing 编辑器的颜色。

图 4. 从首选项页面控制 Swing 编辑器的颜色

回页首

Workbench 知晓性

由于大多数编辑器最初被设计为独立的 Java 应用程序设计,所以它们不注意 Workbench 的存在。它们可能不能处理 Platform 的一些环境属性,这就限制了编辑器与 Platform 集成的亲密度。为了给用户提供一个更平滑更一致的开发体验,开发者和插件供应商应该认真考虑增强他们现有的 Swing 工具从而使其变为 Workbench 知晓的。

例如,Ed 被编码为直接处理基于文件系统的 Java 文件。因此,Platform 的 Java Project 和 Project Reference 与 Ed 无关。在这一部分中,我们将把 JButton添加到 Ed 以启动一个 SWT 对话框,该对话框显示了已编辑的 ThirdParty.java 被引用的项目。从用户角度看,他单击一个 Swing 小窗口,触发了一个显示特定于 Workbench 的信息的 SWT 窗口,这表示 Swing 编辑器、SWT 以及 Workbench 彼此正在紧密交互。

增强编辑器

假设您具有对 Ed 源代码的访问权,您可以添加额外的 Swing 小窗口以获得额外的 Workbench 知晓性功能。将 JButton添加到编辑器的主内容窗格,然后它会启动一个 SWT 对话框。将 JButton的文本设置为“Referenced Project”。

Referenced Project 按钮的事件处理机制的工作方式将与 Save 按钮(请参阅 双向传递:将源代码的更改返回到 workbench 中)的工作方式类似。插件实用程序类将侦听来自这个按钮的事件。实用程序类一接收到 Referenced Project 按钮触发的一个事件对象,它就会执行必要的操作来检索项目引用信息并在 SWT 中显示该信息。

检索项目引用信息

在 SWT 对话框可以被显示之前,插件需要弄明白包含已编辑的 ThirdParty.java 的项目引用了 Workbench 中的哪些项目。这是插件类的工作,而且它可以使用如清单 8 所示的一种方法,其中传入该方法的字符串变量是项目的名称:

清单 8. 检索项目引用信息

private String[] getReferencedProjectArray(String arg) {
String[] projectNameArray = null;

try {
IProject[] referencedProjects =
ResourcesPlugin.getWorkspace().getRoot().getProject(
arg).getReferencedProjects();

int referencedProjectsLength = referencedProjects.length;

if (referencedProjectsLength == 0) {
projectNameArray = new String[1];
projectNameArray[0] = “none”;
}
else {
projectNameArray = new String[referencedProjectsLength];
for (int i=0; i < referencedProjectsLength; i++) {
projectNameArray[i] = referencedProjects[i].getName();
}
}
return projectNameArray;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

SWT 对话框

Project Referenced SWT 对话到底应该会是什么样子要由插件 GUI 设计师决定。在这个示例中,一个带有 List 对象的简单的 SWT Shell(要显示引用的项目)就足够了:

清单 9. 带有 List 对象的 SWT Shell

public class SWTProjectReferenceFrame implements Runnable {
private Shell shell;
private Display display;
Thread myThread;

public void run() {
open();
}

public void open() {
display = new Display();
shell = new Shell(display);
shell.setLayout(new org.eclipse.swt.layout.GridLayout());
shell.setText(“Projects Referenced - SWT Frame”);
shell.setSize(400, 400);
createListGroup();
shell.open();

while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
EditorintegrationPlugin.getDefault().getEd().repaint();
display.sleep();
}
}
myThread = null; // disposing the thread when the SWT window is disposed.
}

// Other methods appear here …
}

方法 createListGroup() 准备了 List 对象并设置其内容以包含 projectNameArray(请参阅 检索项目引用信息)。

清单 10. 准备 List 对象

private void createListGroup() {
Group listGroup = new Group(shell, SWT.NULL);
listGroup.setLayout(new GridLayout());
listGroup.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL |
GridData.HORIZONTAL_ALIGN_FILL |
GridData.VERTICAL_ALIGN_FILL));
listGroup.setText(“listGroup”);

List list = new List(listGroup, SWT.V_SCROLL);
list.setItems(projectNameArray);
}

根据启动 SWT 对话框的方式,您可能需要在一个单独的线程(如清单 10 中的 myThread 对象所指出的那样)中执行 SWT 窗口以避免在 Swing 编辑器中的重绘制(repaint)问题。

图 5中显示了 Swing按钮启动一个 SWT 框架。

图 5. 从 Swing 按钮启动一个 SWT 框架

回页首

结束语

这里描述的这些技术提供了一个临时的解决方案,它可以帮助您快速地将基于 Swing 的工具集成到 Eclipse Platform 中。但是,只要有可能,您就应该在现有的 Swing 小窗口上使用紧密集成的 SWT/JFace 组件。例如,编辑器应该用 Eclipse Platform 的 Preference Page 框架作为配置插件的中心入口点,而不是用各个引用对话框框架来处理多个用户引用。

尽管本文中的这些概念相对简单且易于实现,但是请不要将 Swing 小窗口作为永久设备留在插件中。要控制和利用 Eclipse 项目中的所有服务,您就应该逐渐减少插件中陈旧的 Swing 代码的数量以便支持 Eclipse 项目提供的各种框架。