eclipse 插件教程
不幸的是,第一次在Eclipse中进行操作会非常耗时且令人沮丧。 Eclipse框架非常庞大,强大,有时甚至很复杂。 可能很难弄清楚哪些功能可用以及如何使用它们。
本教程介绍了自动化简单的Java重构任务所需的所有eclipse功能的基础。 它显示了如何在菜单中添加新项目以及如何分析,修改和格式化Java源代码。 它还显示了如何使用对话框与用户进行交流。
它分为两个部分。 这篇文章解释了所有需要的理论。 在本部分的最后,您将已经对Eclipse框架有了足够的了解,只需稍加搜索即可完成该插件。 实际上,我们将创建一个插件,该插件将新项目添加到菜单中并收集执行重构所需的所有信息。
本教程的下一部分将展示如何创建对话框以及如何从插件修改Java源代码。 它尚未发布。
样本插件
我们创建具有两个功能的示例插件:
- 检查非空参数–修改所选方法以检查其参数是否不为
null
, - 自定义生成toString –将
toString
方法添加到选定的类。
这两个功能都将在源菜单中添加一个新项。 仅当用户选择Java方法时,“检查非空参数”项才会启用。 该功能显示一个对话框,允许用户选择方法参数的子集。 然后修改选定的方法以检查选定的参数是否为空:
if (arg1==null || arg2==null || ... || argn==null)
throw new IllegalStateException("The parameter may not be null.");
仅当用户选择一个Java类时,才会启用Custom generate toString项目。 它将显示一个对话框及其所有属性的列表。 用户选择属于toString方法的属性。 如果用户选择的属性少于四个,则此功能将以下代码添加到类中:
@Override
public String toString() {
StringBuilder builder = new StringBuilder(this.getClass()
.getSimpleName());
builder.append(" [ ");
builder.append(b).append(", ").append(c).append(" ]");
return builder.toString();
}
如果用户选择了更多或更少的四个属性,则该功能将以下代码添加到类中:
public String toString() {
StringBuilder builder = new StringBuilder(this.getClass()
.getSimpleName());
builder.append(" [ \n");
builder.append(" a" + ": ").append(a).append("\n");
builder.append(" b" + ": ").append(b).append("\n");
builder.append(" c" + ": ").append(c).append("\n");
builder.append(" d" + ": ").append(d).append("\n");
builder.append(" ]");
return builder.toString();
}
就这些。 该插件在Github上可用。
每个Eclipse版本都有多种风格。 最适合插件编写者的版本称为“ Eclipse for RCP and RAP Developers”。 RCP代表“富客户端平台”,它只是Eclipse平台的另一个名称。
从下载页面下载并安装“用于RCP和RAP开发人员的Eclipse”。
首先要做的是配置目标平台。 目标平台是eclipse的另一个实例。 它表示您的插件将使用的最低配置。 您的插件将针对目标平台进行编译。 它还将安装到其中并在您要对其进行测试时在其中运行。
整个工作空间只能有一个活动目标平台。 尽管这样做更有意义,但它不是特定于项目的。
最简单的方法是开发与运行时相同的Eclipse版本。 这是默认选项。 在这种情况下,您要做的就是向其中添加eclipse SDK。
安装Eclipse SDK:
- 转到“帮助”->“安装新软件...”。
- 选择您的Eclipse更新站点,在本例中为“ Eclipse项目更新”
http://download.eclipse.org/eclipse/updates/3.
更新网站。 - 检查Eclipse SDK和Eclipse Platform SDK。
- 单击下一步,接受许可并完成安装。
这就对了。 不需要任何其他操作,您就可以创建第一个插件项目了 。
可以单独下载和维护目标平台。 如果要与较早的版本兼容,或者要对目标平台配置有更大的控制权,请使用此选项。
如果您不感兴趣,请跳到下一章。
查找并下载您认为用户将拥有的任何内容的SDK。 如果找不到SDK,也可以使用“常规”版本。 但是,如果下载SDK,则将提供源代码和javadocs。
例如,我们的插件需要Eclipse Indigo版本。 Eclipse Indigo的版本号是3.7,因此我们必须下载Eclipse 3.7 SDK 。 归档发行版页面上提供了更早版本的Eclipse SDK的完整列表。
我们的插件将仅依赖于eclipse本身,因此我们要做的就是在某个地方解压缩下载的SDK。 如果需要其他插件,我们也必须搜索并下载其SDK。 我们还将解压缩它们并复制到与Eclipse SDK相同的目录中。
现在,我们必须配置RCP Eclipse以使用准备好的目标平台。
定义并激活目标平台:
- 转到“窗口”->“首选项”->“插件开发”->“目标平台”。
- 单击添加。
- 选择“无:从空目标定义开始”,然后单击下一步。
- 填写目标名称。
- 单击添加,选择目录,浏览至解压缩的Eclipse SDK并完成。
- 将新的目标平台检查为“有效”。
最后,转到“插件开发”首选项页面,然后选中“在Java搜索中包括来自目标的所有插件”。
本章介绍如何创建一个简单的插件项目以及如何对其进行调试。 简单的插件没有任何用处。 它只能显示一条消息以证明其存在。
在本章的最后,我们将删除示例消息,最后得到一个空的插件框架。
我们将使用Eclipse向导来生成插件。 从包资源管理器中调用向导:
- 右键点击包浏览器,
- 选择“新建”->“其他..”。
- 选择“插件项目”,然后单击“下一步”。
该向导有多个页面。 在第一个上配置项目名称和目标平台。 您可以根据需要使用任何项目名称,但是习惯上是以根java软件包命名该项目。 例如,由于我们要将所有类都放入org.meri.eclipse.defensiveapitools
包中,因此我们的项目名称为org.meri.eclipse.defensiveapitools
目标平台字段包含您要开发的Eclipse版本。 如果有人要使用您的插件,则将要求他下载数量相等或更大的Eclipse。 一个旧的不兼容的Eclipse将拒绝加载它。 我们可以为当前的Eclipse开发很好,所以我们选择3.7。
点击下一步'。
第二页包含基本项目信息。 随意填写ID,插件版本,名称和提供程序。 第一个重要参数是执行环境。 该插件将仅在指定的Java上运行,或者永远不在Java上运行。 在较早的JVM上运行的Eclipse只会忽略它。 我们选择了J2SE-1.6。
验证:
- 复选框“ Generate a activator,Java…”被选中,
- 复选框“此插件将为用户界面做出贡献”已选中,
- “是否要创建富客户端平台应用程序”的答案是否定的。
点击下一步'。
选择“ Hello,World Command”模板,然后单击“ Finish”。 这将创建带有示例菜单项的新插件。
该插件仅在正在运行的Eclipse中起作用。 Eclipse支持手动和自动JUnit测试。 在这两种情况下,都将在第一章中配置的目标平台内安装并运行该插件。
本章仅显示如何进行手动测试。 请参考其他资源,以学习如何为eclipse插件编写junit测试。
安装并运行插件:
- 右键点击插件项目,
- 单击“调试为”->“ Eclipse应用程序”。
系统将启动新的Eclipse实例。 它的主菜单有一个新条目,称为“样本菜单”。
现在,您有两个正在运行的Eclipse实例。 一个用于开发,另一个用于测试。 日蚀在开发人员内部运行。 所有调试工具均可用。 您可以放置断点,检查变量等:
- 在开发蚀中打开生成的
SampleHandler
类, - 将断点放在
execute
方法中, - 回到Eclipse,
- 选择“示例菜单”和“示例命令”
执行将在新的断点处停止。
我们已经看到该插件有效,因此我们可以从中删除生成的示例菜单。
删除示例菜单项及其处理程序:
- 打开plugin.xml文件,转到扩展选项卡并删除所有扩展。
- 找到并删除生成的
SampleHandler
类。
plugin.xml内的plugin
标签现在应该为空。 打开plugin.xml文件,然后转到plugin.xml选项卡:
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
</plugin>
Eclipse是一个巨大的框架,您可以在其中安装无限数量的插件。 这创建了一个庞大的功能和插件系统,它们必须相互配合。 为了使该系统保持解耦和尽可能扩展,Eclipse框架使用适配器设计模式 。 这种模式非常普遍,无论您要编写哪种插件,您都可能会遇到它。
此设计模式将一个类或接口转换为另一个类或接口。 执行转换的类称为适配器。 该模式具有两种不同的风格,并且eclipse框架都支持。 两种风格之间的区别在于谁创建了适配器。 它可以直接由要转换的对象完成,也可以由独立的适配器工厂完成。
第一个子章节显示了如何编写适配器。 第二个子章节是关于能够创建自己的适配器的对象,第三个子章节是关于独立适配器工厂的。 最后一个子章节将所有内容放在一起,并说明如何转换未知类型的对象。
适配器是将一种类型转换为另一种类型的对象。 它必须表示其他类型,例如,如果将对象转换为类,则必须扩展该类。 如果将它们转换为接口,则必须实现该接口。
通常,适配器会转换具有所有必需功能但没有正确API的对象。 否则,典型的适配器包含很少的逻辑。 它只包装原始对象并将所有工作委托给它。
以下适配器能够将Minus
接口的实现转换为Plus
接口:
public class MinusToPlusAdapter implements Plus {
private final Minus adaptee;
public MinusToPlusAdapter(Minus minus) {
super();
this.adaptee = minus;
}
@Override
public int plus(int x, int y) {
return adaptee.minus(x, -y);
}
}
在此设计模式的简单版本中,要转换的对象创建了自己的适配器。
我们将展示如何创建与Eclipse框架兼容的适应性对象。 该子章节的其余部分列出了此适配器样式风格的优点和缺点。
自适应对象必须实现IAdaptable
接口。 该接口只有一个方法getAdapter(Class type)
。 它返回一个适配器到请求的类型,或者返回null
。
适应对象:
public class MinusImpl implements Minus, IAdaptable {
public int minus(int x, int y) {
return x - y;
}
public Object getAdapter(Class type) {
if (Plus.class.equals(type))
return new MinusToPlusAdapter(this);
return null;
}
}
getAdapter
方法可能会也可能不会调用全局适配器管理器来创建适配器。 一些Eclipse对象调用它,有些则没有。
自适应对象易于使用和调试。 该模式有助于保持类和接口层次结构的整洁。 它还提供了转换类型和所需类型之间的一些解耦。
在以下情况下使用它:
- 转换类型已经实现了太多接口。
- 转换后的类型必须与两个不同的特性兼容,并且每个特性都要求它扩展另一个类。
- 您希望将转换后的类型和所需的接口/类分开。
- 适配器需要访问方法的私有字段。
仅依赖于此模式版本的插件是不可扩展的。 第三方插件将无法向其中添加新的适配器。
此模式的第二个版本使用独立的工厂来创建适配器。
我们将展示如何在eclipse框架内调用适配器工厂。 该子章节的其余部分列出了此适配器样式风格的优点和缺点。
适配器由适配器工厂创建。 为了实现它们的独立性,适配器工厂被隐藏在全局适配器管理器的后面。 客户端代码从不直接与适配器工厂通信。
适配器管理器公开一个getAdapter(Object obj, Class type)
方法,该方法将调用委派给已安装的适配器工厂。 此方法返回适配器或null
。
使用适配器管理器创建适配器:
(Plus) Platform.getAdapterManager().getAdapter(minus, Plus.class);
适配器工厂可以通过编程方式或在plugin.xml中注册到适配器管理器中。 由于我们的插件不需要执行此操作,因此我们将忽略该信息。 阅读eclipse corner文章或Eclipse Adapters教程以获取更多信息。
注意:不允许适配器工厂调用已转换对象的getAdapter(Class type)
方法。 这将导致无限循环,因为可适配对象的getAdapter
方法可能会调用适配器管理器。
适配器工厂导致高度的去耦和可扩展性。 原始对象和所需类型的分离是绝对的。 它们之间没有依赖性。 而是,独立的适配器工厂取决于这两者。
向适配器管理器询问适配器可以使您的功能扩展。 任何人都可以贡献适配器以将其对象与您的插件集成。
使用它来:
- 使您的插件可由第三方插件编写者扩展,
- 集成两个插件。
去耦具有更高的复杂度。 如果出现问题,可能很难找出故障适配器的来源。 同样,与使用该模式的“可适配对象”版本相比,找出可用的适配器耗时更多。
如果您希望其他人扩展您的插件,请记录需要哪些适配器。 还要记录您要添加到系统中的适配器工厂。 在xml文件中查找所有这些信息可能非常耗时。