当前页面: 开发资料首页 → Eclipse 专题 → 使用 XML: 创建项目
摘要: 本文继续讨论 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 文档和源代码(幸运的话才会有)。
开发过程通常要反复试验 - 编写修改代码直到它能做出点有意义的事情。遗憾的是,通常我认为自己了解了某些东西,转而开始新任务,结果才发现自己错了!直至最后,我才相信自己真的懂了。我所面临的问题单独来看没有一个是极为困难的,但这些问题合并在一起却成了难题了。随着越来越多文章的发表,(缺乏)文档的问题最终会不存在。
<table align="right" border="0" cellspacing="0" cellpadding="0" width="40%"><tr><td width="10"></td><td><table border="1" cellspacing="0" cellpadding="5" width="100%"><tr><td bgcolor="#eeeeee"> “使用 XML”论坛我们有了一个更便于使用的新论坛软件,因此请您务必通过单击本文顶部或底部的 讨论来参与有关 XML、其它专栏项目或 Eclipse 的讨论。
</td></tr></table></td></tr></table>XM 插件的发展
在前一篇专栏文章“ Integrating XM and Eclipse”的结束部分,我粗略地完成了 XM 和 Eclipse 的集成。我在上下文菜单中添加了一项,用户可以选择它来运行 XM。我知道这只是第一步,但是当我(和 Pineapplesoft 的其他成员)开始使用它,我觉得我需要做得更好。我特别不满意的是:
.xmp
文件容易引起混淆。大多数情况下它是空的,因为只需要它作为单击目标。最初 XM 不需要配置文件,这是其魅力所在。
清楚了这些缺点,所以我决定在不久的将来 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 是一个通用导航器,它列出了项目中的资源(文件)。
要创建新项目,您需要一个新目录和几个由 Eclipse 管理的配置文件。注:只在工作空间中创建一个新目录还不够 - Eclipse 无法将其识别为项目。
项目性质
项目的主配置文件称为
性质(nature)是项目类型的标识。例如,Java 项目具有 Java 性质。Eclipse 使用项目性质来控制与用户的交互。性质可以启用或禁用菜单项,因此具有 Java 性质的项目在菜单中含有特定于 Java 的项。
一个项目可以有多个性质。例如,插件项目既是 Java 项目(毕竟,插件是用 Java 语言编写的)又是插件项目。实际上,它具有这两种菜单项。 和其它 Eclipse 标识一样,性质标识从域名的倒序开始,这和包名没什么不同。例如,Java 性质标识是
由于了解了这一点,所以我意识到正是项目的性质使空的
我将
如果将清单 1 和早先发布的代码作个比较,您会看到下列变化: 新建 XM 项目向导
显然清单 1 中的清单文件只在项目已被声明为 XM 性质时才工作。通用向导创建的项目不带性质。因此要测试
清单 1中的代码,我首先得提供 XM 项目向导。
Eclipse 向导
Eclipse 的可扩展性是令人难以置信的,这一点在它如何处理向导中得到了体现。利用 Eclipse,有好几个插件可以用于向导。项目向导利用了这一特性。 当用户在菜单中选择
New Project时,就会显示如图 2 所示的向导。用户选择要创建的项目类型。尽管 XM 出现在列表中,但是 XM 插件还没有装入。该列表是根据清单文件(
然而,在如图 3 所示的下一屏中,插件已经被装入并且控制了屏幕。这个转变对于用户来说是非常平滑的:向导没有任何闪动或更改。实际上,除非用户编写了插件,否则他可能永远都不会意识到已经装入了新插件。 为完成这一透明集成,Eclipse 将向导分成三组对象: XM 实现
XM 用
往往在清单文件中将
装入插件后,容器调用
接下来,容器调用如清单 4 所示的
向导为其所注册的每个页面都调用
用户单击 Finish
当用户单击
Finish时,
创建项目会更改工作空间,因为它添加了目录和文件。在整个更改过程中,向导都会与工作空间保持同步。最简便的解决方案就是用
更改工作空间的代码必须从
项目创建和进度的长度是用工作单元进行报告的。定义单元所表示的内容则由您来决定。例如,处理文件时,每个单元就可以是一个文件。 要执行线程,请调用容器中的
项目创建
真正的项目创建在
要创建新项目,请遵循以下这些步骤: 一旦您创建并打开该项目,您就可以设置它的特性。它们用 Eclipse 特性进行存储。正如您在
清单 6中所看到的那样,向导为 XM 构建器设置了一些特性。您应当熟悉那些特性,因为它们与“
Integrating XM and Eclipse”中所介绍的
除了上述之外,向导用缺省目录(通常是
计划中
如果您从在线资源库(请参阅
参考资料)下载了源代码,您会发现插件也提供了一个构建器。该构建器就是我下篇专栏文章的主题。
本文演示了 Eclipse 给予作为插件开发人员的您以极大的自由来控制用户的操作过程。因此,您的插件几乎可以扩展用户界面的任何方面。 关于作者<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td colspan="3"></td></tr><tr align="left" valign="top"><td></td><td></td><td width="100%"> Beno?t Marchal 是住在比利时那幕尔的顾问和作家。他是
XML by Example
一书的作者,他还撰写了其它 XML 书籍,这些书籍讨论了 XML 标准的最新特性,包括最终的 XML Schema 建议书和最新的 XSL 开发。可以在
www.marchal.com上获取更多的详细信息。可以通过
bmarchal@pineapplesoft.com与 Beno?t 联系。
.project
(在 UNIX 文件系统中,用点来标记隐藏文件)。它包含了有关如何构建项目以及项目性质的信息。
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. 新扩展点
<table bgcolor="#eeeeee" width="100%" cellpadding="5" cellspacing="0" border="1"><tr><td>
</td></tr></table>
filter
标记代替了
nameFilter
属性。
filter
匹配项目性质,
nameFilter
匹配文件名。
enablesFor
属性被改成
+
,这意味着可以选择项目中的多个文件。这就为用户提供了方便。
XMRunner
类基本上没有更改。但是,我已经缩短了包名,以便可以少打一些字。
<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>plugin.xml
)填充的。
NewXMProjectWizard
类实现向导。该类实现
INewWizard
接口。实际上,最简便的解决方案是从
Wizard
派生,因为该类是由
INewWizard
所定义的大多数方法的缺省实现。
NewXMProjectWizard
注册为扩展点。清单 2 是来自清单文件的有关摘录。请注意它为向导声明了类别。该类别组合了几个 XM 向导。
清单 2. 向导扩展点
<table bgcolor="#eeeeee" width="100%" cellpadding="5" cellspacing="0" border="1"><tr><td>
</td></tr></table>
wizard
是向导中的新标记,但是它与前一篇专栏文章中所介绍的
view
非常相似,因此熟悉它应该很容易。唯一的新东西是
project
属性:设置成
true
时,它会把向导添加到新项目列表中。若没有这个属性,则向导列入“Other”类别。
init()
。
NewXMProjectWizard
需要进行少量的初始化工作。首先它调用
setNeedsProgressMonitor()
来请求进度条。创建项目时,它让进度条逐渐变满,如清单 3 所示。
清单 3. init() 方法
<table bgcolor="#eeeeee" width="100%" cellpadding="5" cellspacing="0" border="1"><tr><td>
</td></tr></table>
public void init(IWorkbench workbench,
IStructuredSelection selection)
{
setNeedsProgressMonitor(true);
}
addPages()
。该方法注册向导页面。
NewXMProjectWizard
只需一个提示输入项目名和位置的页面。Eclipse 用类
WizardNewProjectCreationPage
方便地提供了这样一个页面(您可以在
图 2中看到该页面)。
清单 4. addPages() 方法
<table bgcolor="#eeeeee" width="100%" cellpadding="5" cellspacing="0" border="1"><tr><td>
</td></tr></table>
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()
。在本案例中,只有一个页面。
performFinish()
方法开始执行。清单 5 是该方法内容。该方法中并没有多少操作。
createProject()
中包含了创建项目的代码块,
performFinish()
间接调用它。
清单 5. performFinish() 方法
<table bgcolor="#eeeeee" width="100%" cellpadding="5" cellspacing="0" border="1"><tr><td>
</td></tr></table>
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)。次序在该方法中非常重要:如果您的代码不按照正确的次序运行,则向导会失败(通常给出令人迷惑的错误消息)。
IWorkspaceRoot
的实例的工作空间根。Eclipse 提供了一个便捷的插件(
ResourcesPlugin
),通过该插件您可以访问包括工作空间在内的资源。再强调一次,这些是 Eclipse 资源,比如文件和目录。
IWorkspaceRoot
上调用
getProject()
(我个人认为该方法本应被称为
newProject()
,因为它创建了项目)。
newProjectDescription()
方法创建一个空的项目描述。项目描述包含了有关项目的特定类型的信息,包括它在文件系统上的位置。
create()
方法创建项目。
.xmp
文件一样。
src
、
rules
和
publish
)、样本 XML 文档和简单的样式表填充该项目。这就为用户提供了方便。
<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>
<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>
<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>
↑返回目录
前一篇: 使用 XML: Eclipse 中的布局、属性和首选项
后一篇: 使用 XML: 使用 XML:集成 XM 和 Eclipse