IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  XML  >

使用 XML: 创建项目

将新向导添加到 Eclipse 中

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 初级

Benoit Marchal (bmarchal@pineapplesoft.com), 顾问, Pineapplesoft

2003 年 1 月 01 日

本文继续讨论 Eclipse 与 XM 的集成,Eclipse 是 IBM 的开放源码项目,用于构建针对 Java 开发人员的可扩展集成开发环境(IDE);而 XM 是 Benoît Marchal 的简单内容管理解决方案。在这篇专栏文章中,Benoît 添加了初始化新项目的向导。在此期间,他把自己辛苦得来的有关 Eclipse 平台的发现与大家分享。

如果您从一开始就一直学习本项目,那么就会了解我非常热衷于 Eclipse。就像 Emacs 迷告诉您的那样,好的开发环境必须是可扩展 并且是可配置的。Eclipse 是在综合考虑了这两方面之后推出的,但是与其享有盛誉的“前辈”Emacs 不同的是,Eclipse 还提供了新式的用户界面。

SWT 的可移植性

Eclipse 的优点之一是它修正了 Java 技术中我所认为的一个最大败笔:用户界面库。正如我所说的那样,Eclipse 使用标准窗口构件工具箱(Standard Widget Toolkit,SWT),SWT 结合了抽象窗口工具箱(Abstract Windowing Toolkit,AWT)的最佳特性、本机控件的使用和 Swing 丰富的窗口构件集。最终有可能设计出与本机用户界面行为相似的成熟的用户界面。

SWT 受到的大多数批评都集中在可移植性方面。由于 SWT 不属于 JDK(Java 开发工具箱),因此它在某些平台上可能无法使用。幸运的是,Eclipse 团队似乎承诺要将 SWT 移植到尽量多的平台上,因此实际上这已不成问题了。

我很想测试 SWT 的可移植性,因此当出现了 Macintosh 构建时,我立刻下载了它。尽管 Mac 移植仍然处于开发过程中,但它还是相当稳定的。但是我印象最深的是 SWT 及其绘制本机 Aqua 控件的能力。





回页首


关于文档

使用新项目并编写有关它们的文章是很有意思的,但是也有缺陷:新项目的文档编制往往不够完善。Eclipse 也不例外。撰写本文 - 或者更确切地说是为其编码 - 需要进行许多研究。其文档仅限于几篇有关原理的文章、API 文档和源代码(幸运的话才会有)。

开发过程通常要反复试验 - 编写修改代码直到它能做出点有意义的事情。遗憾的是,通常我认为自己了解了某些东西,转而开始新任务,结果才发现自己错了!直至最后,我才相信自己真的懂了。我所面临的问题单独来看没有一个是极为困难的,但这些问题合并在一起却成了难题了。随着越来越多文章的发表,(缺乏)文档的问题最终会不存在。

“使用 XML”论坛

我们有了一个更便于使用的新论坛软件,因此请您务必通过单击本文顶部或底部的 讨论来参与有关 XML、其它专栏项目或 Eclipse 的讨论。





回页首


XM 插件的发展

在前一篇专栏文章“ Integrating XM and Eclipse”的结束部分,我粗略地完成了 XM 和 Eclipse 的集成。我在上下文菜单中添加了一项,用户可以选择它来运行 XM。我知道这只是第一步,但是当我(和 Pineapplesoft 的其他成员)开始使用它,我觉得我需要做得更好。我特别不满意的是:

  • 启动新项目很困难。我不得不运行 New Project向导,然后手工创建几个文件。该向导应当能够做所有事情。
  • .xmp 文件容易引起混淆。大多数情况下它是空的,因为只需要它作为单击目标。最初 XM 不需要配置文件,这是其魅力所在。
  • 单击鼠标右键是 Windows/KDE/Gnome 动作。在 Mac 上,单击鼠标右键最好留给复杂的不常用的操作使用。我必须拿出移植性更好的界面。可以用 Eclipse 注册构建器(本质上是编译器)。当项目发生更改时,Eclipse 会自动调用相应的构建器。

清楚了这些缺点,所以我决定在不久的将来 XM 插件应该包括 New Project向导并且包括在项目构建期间调用 XM 的能力。这两个特性通过扩展点(extension point)来实现(请参考 参考资料中的“Use Eclipse to build a user interface for XM”一文以获取有关扩展点的更多详细信息)。新向导的扩展点是 org.eclipse.ui.newWizards ,它使用接口 org.eclipse.ui.INewPlugin 。构建器的扩展点是 org.eclipse.core.resources.builders ,它使用接口 org.eclipse.core.resources.IncrementalProjectBuilder





回页首


新建项目向导

新建项目(New Project)向导和构建器是相关的。例如,在创建新项目时 Eclipse 会自动调用构建器。如果您从在线资源库中下载了该代码,您会看到这两者都已经被实现了。本文讨论向导,而下个月的文章将讨论构建器。

文件和项目目录

让我们从一些定义开始。对于 Eclipse 而言, 项目(project)是项目目录中文件(源文件、配置文件、已编译文件及其它文件)的集合。在 Eclipse 术语中,文件和目录都称为 资源(resource)。不要把 Eclipse 资源(文件)和 Java 资源(用于本地化的字符串)搞混了。

用户可用的项目列表组成了 工作空间(workspace)。缺省情况下项目存储在 eclipse/workspace 目录中,但是用户可以在任何地方创建项目。

用户通过 导航器(navigator)面板和项目交互,如图 1 所示。此外,插件可以提供专门的导航器。图 1 是一个通用导航器,它列出了项目中的资源(文件)。


图 1. Eclipse 导航器
Eclipse 导航器

要创建新项目,您需要一个新目录和几个由 Eclipse 管理的配置文件。注:只在工作空间中创建一个新目录还不够 - Eclipse 无法将其识别为项目。

项目性质

项目的主配置文件称为 .project (在 UNIX 文件系统中,用点来标记隐藏文件)。它包含了有关如何构建项目以及项目性质的信息。

性质(nature)是项目类型的标识。例如,Java 项目具有 Java 性质。Eclipse 使用项目性质来控制与用户的交互。性质可以启用或禁用菜单项,因此具有 Java 性质的项目在菜单中含有特定于 Java 的项。

一个项目可以有多个性质。例如,插件项目既是 Java 项目(毕竟,插件是用 Java 语言编写的)又是插件项目。实际上,它具有这两种菜单项。

和其它 Eclipse 标识一样,性质标识从域名的倒序开始,这和包名没什么不同。例如,Java 性质标识是 org.eclipse.jdt.core.javanature 。注意别把该标识和类/包名搞混了。请参考 参考资料一节中的“Use Eclipse to build a user interface for XM”以获取有关标识的更多详细信息。

由于了解了这一点,所以我意识到正是项目的性质使空的 .xmp 文件(在前一篇专栏文章中做过介绍)变得多余了。如果我为 XM 项目定义特定性质,那么就有可能将 Integrating XM and Eclipse中所介绍的 Run XM菜单项与那些项目进行关联。

我将 org.ananas.xm.eclipse.xmnature 定义为 XM 的项目性质。清单 1 说明我是如何更改清单文件( plugin.xml )以反映这一点的。


清单 1. 新扩展点
<extension point="org.eclipse.ui.popupMenus">
<objectContribution adaptable="true"
objectClass="org.eclipse.core.resources.IResource"
id="org.ananas.xm.eclipse.popupMenu">
        
        <filter name="projectNature"
value="org.ananas.xm.eclipse.xmnature">
</filter>
<action label="Run XM"
tooltip="Call XM to publish the site."
class="org.ananas.xm.eclipse.XMRunner"
menubarPath="additions"
        
        enablesFor="+"
id="org.ananas.xm.eclipse.popMenu.action">
</action>
</objectContribution>
</extension>
      
      

如果将清单 1 和早先发布的代码作个比较,您会看到下列变化:

  • filter 标记代替了 nameFilter 属性。 filter 匹配项目性质, nameFilter 匹配文件名。
  • enablesFor 属性被改成 + ,这意味着可以选择项目中的多个文件。这就为用户提供了方便。
  • XMRunner 类基本上没有更改。但是,我已经缩短了包名,以便可以少打一些字。




回页首


新建 XM 项目向导

显然清单 1 中的清单文件只在项目已被声明为 XM 性质时才工作。通用向导创建的项目不带性质。因此要测试 清单 1中的代码,我首先得提供 XM 项目向导。

Eclipse 向导

Eclipse 的可扩展性是令人难以置信的,这一点在它如何处理向导中得到了体现。利用 Eclipse,有好几个插件可以用于向导。项目向导利用了这一特性。

当用户在菜单中选择 New Project时,就会显示如图 2 所示的向导。用户选择要创建的项目类型。尽管 XM 出现在列表中,但是 XM 插件还没有装入。该列表是根据清单文件( plugin.xml )填充的。


图 2. 新建项目向导
新建项目向导

然而,在如图 3 所示的下一屏中,插件已经被装入并且控制了屏幕。这个转变对于用户来说是非常平滑的:向导没有任何闪动或更改。实际上,除非用户编写了插件,否则他可能永远都不会意识到已经装入了新插件。


图 3. 已装入了插件
已装入了插件

为完成这一透明集成,Eclipse 将向导分成三组对象:

  • 容器是带有按钮的对话框。
  • 向导响应用户的操作。容器和一个或多个向导交互以响应用户操作。
  • 页面画出容器中的控件。用户按一下 Next 按钮,就装入一个新页面。在 图 3中,页面管理表示项目名称(project name)和目录(directory)的域。

XM 实现

XM 用 NewXMProjectWizard 类实现向导。该类实现 INewWizard 接口。实际上,最简便的解决方案是从 Wizard 派生,因为该类是由 INewWizard 所定义的大多数方法的缺省实现。

往往在清单文件中将 NewXMProjectWizard 注册为扩展点。清单 2 是来自清单文件的有关摘录。请注意它为向导声明了类别。该类别组合了几个 XM 向导。


清单 2. 向导扩展点
<extension point="org.eclipse.ui.newWizards">
<category name="ananas.org"
id="org.ananas.xm.eclipse.newWizards">
</category>
<wizard name="XM Project"
icon="icons/newproject16.gif"
category="org.ananas.xm.eclipse.newWizards"
class="org.ananas.xm.eclipse.NewXMProjectWizard"
        
        project="true"
id="org.ananas.xm.eclipse.newproject">
<description>Create an XM project.</description>
</wizard>
</extension>
      
      

wizard 是向导中的新标记,但是它与前一篇专栏文章中所介绍的 view 非常相似,因此熟悉它应该很容易。唯一的新东西是 project 属性:设置成 true 时,它会把向导添加到新项目列表中。若没有这个属性,则向导列入“Other”类别。

装入插件后,容器调用 init()NewXMProjectWizard 需要进行少量的初始化工作。首先它调用 setNeedsProgressMonitor() 来请求进度条。创建项目时,它让进度条逐渐变满,如清单 3 所示。


清单 3. init() 方法
public void init(IWorkbench workbench,
IStructuredSelection selection)
{
setNeedsProgressMonitor(true);
}

接下来,容器调用如清单 4 所示的 addPages() 。该方法注册向导页面。 NewXMProjectWizard 只需一个提示输入项目名和位置的页面。Eclipse 用类 WizardNewProjectCreationPage 方便地提供了这样一个页面(您可以在 图 2中看到该页面)。


清单 4. addPages() 方法
public void addPages()
{
super.addPages();
namePage = new WizardNewProjectCreationPage("NewXMProjectWizard");
namePage.setTitle(Resources.getString("eclipse.newprojectname"));
namePage.setDescription(Resources.getString("eclipse.newprojectdescription"));
namePage.setImageDescriptor(ImageDescriptor.createFromFile(getClass(),
"/org/ananas/xm/eclipse/resources/newproject58.gif"));
        
        addPage(namePage);
}
      
      

向导为其所注册的每个页面都调用 addPage() 。在本案例中,只有一个页面。

用户单击 Finish

当用户单击 Finish时, performFinish() 方法开始执行。清单 5 是该方法内容。该方法中并没有多少操作。 createProject() 中包含了创建项目的代码块, performFinish() 间接调用它。


清单 5. performFinish() 方法
public boolean performFinish()
{
try
{
WorkspaceModifyOperation op =
new WorkspaceModifyOperation()
{
protected void execute(IProgressMonitor monitor)
{
createProject(monitor != null ?
monitor : new NullProgressMonitor());
}
});
getContainer().run(false,true,op);
}
catch(InvocationTargetException x)
{
reportError(x);
return false;
}
catch(InterruptedException x)
{
reportError(x);
return false;
}
return true;
}

创建项目会更改工作空间,因为它添加了目录和文件。在整个更改过程中,向导都会与工作空间保持同步。最简便的解决方案就是用 WorkspaceModifyOperation 的子代执行项目创建。

更改工作空间的代码必须从 execute() 方法进行调用。在 清单 5中,它只调用 createProject()execute()IProgressMonitor 作为参数。如果项目创建要花一些时间,那么向导会通过该参数报告其进度。容器用它来更新进度条。

IProgressMonitor 中最有用的方法是:

  • beginTask() ,它将在操作开始前被调用。它带有操作的描述和持续时间。
  • worked() 报告进度。它通常更新进度条。
  • done() 必须在创建项目时进行调用。
  • subTask() 可以让您更改描述。

项目创建和进度的长度是用工作单元进行报告的。定义单元所表示的内容则由您来决定。例如,处理文件时,每个单元就可以是一个文件。

要执行线程,请调用容器中的 run() 方法。该容器使自己的进度条与 IProgressMonitor 保持同步。

项目创建

真正的项目创建在 createProject() 中进行(请参阅 清单 6)。次序在该方法中非常重要:如果您的代码不按照正确的次序运行,则向导会失败(通常给出令人迷惑的错误消息)。

要创建新项目,请遵循以下这些步骤:

  1. 检索作为 IWorkspaceRoot 的实例的工作空间根。Eclipse 提供了一个便捷的插件( ResourcesPlugin ),通过该插件您可以访问包括工作空间在内的资源。再强调一次,这些是 Eclipse 资源,比如文件和目录。
  2. IWorkspaceRoot 上调用 getProject() (我个人认为该方法本应被称为 newProject() ,因为它创建了项目)。
  3. newProjectDescription() 方法创建一个空的项目描述。项目描述包含了有关项目的特定类型的信息,包括它在文件系统上的位置。
  4. 如果用户选择缺省位置(位于工作空间目录下),请转到 下一步。否则,请在描述对象上设置位置。出于一些原因,如果您将项目位置显式地设置成它的缺省值,那么项目创建就会失败。
  5. 注册项目性质(如果有的话)。这是一组字符串标识。
  6. 注册项目构建器(或编译器)。虽然我将在下一篇文章中才对此进行讨论,但是 XM 现在就可以用作构建器。
  7. create() 方法创建项目。
  8. 最后,打开新创建的项目。

一旦您创建并打开该项目,您就可以设置它的特性。它们用 Eclipse 特性进行存储。正如您在 清单 6中所看到的那样,向导为 XM 构建器设置了一些特性。您应当熟悉那些特性,因为它们与“ Integrating XM and Eclipse”中所介绍的 .xmp 文件一样。

除了上述之外,向导用缺省目录(通常是 srcrulespublish )、样本 XML 文档和简单的样式表填充该项目。这就为用户提供了方便。





回页首


计划中

如果您从在线资源库(请参阅 参考资料)下载了源代码,您会发现插件也提供了一个构建器。该构建器就是我下篇专栏文章的主题。

本文演示了 Eclipse 给予作为插件开发人员的您以极大的自由来控制用户的操作过程。因此,您的插件几乎可以扩展用户界面的任何方面。



参考资料



关于作者

Author photo

Benoît Marchal 是住在比利时那幕尔的顾问和作家。他是 XML by Example 一书的作者,他还撰写了其它 XML 书籍,这些书籍讨论了 XML 标准的最新特性,包括最终的 XML Schema 建议书和最新的 XSL 开发。可以在 www.marchal.com上获取更多的详细信息。可以通过 bmarchal@pineapplesoft.com与 Benoît 联系。




对本文的评价










回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款