枫林在线论坛精华区>>程序设计
[340910] 主题: Eclipse零起步系列讲座(八)
作者: little (渺小·Happy^_^)
标题: Eclipse零起步系列讲座(八)[转载]
来自: 192.168.*.*
发贴时间: 2005年04月25日 11:25:02
长度: 7945字

Eclipse零起步系列讲座 (八)

===========================================

(前言)
哈~, 今天我们开始一起学习做插件吧, 其实我觉得到今天我们才开始进入
正题也. 就像
光会吃鱼不行,我们还要学会钓鱼啊.

(正文)

[Hello World 例子]

先新建一个项目, Plug-in Development -> Plug-in Project, 按nex
t
项目名就叫MyPlugin, 按next
plugin的项目结构不用改,按next
在plugin code generator选择 Create a plug-in project using code 
generation
wizard -> hello world, 然后按next,
之后的页面,我们都用默认的,后面我们会讨论如何改的,按finish

现在, hello world这个例子就已经生成好了, 估计你会发现tasks视图会
有错误, 说xx
plugin不能解析之类的话, 所以我要做一些工作台的设置

打开preference -> plugin environment -> target platform, 然
后按 not in
workspace按钮, 这个是pde插件内置的一个设置, 因为我们是做插件, 编
译时肯定

要用到很多eclipse 原有插件的运行库, 做了找个设置之后, pde在编译项
目时就会根据
这个设置,计算构建路径,编译我们的插件.

在eclipse 2.0版本时,做的还没有这么先进, 开发要依赖的插件必须导入
到工作区,作为
java 项目来应用才可以进行编译, 到2.1版本后,这个问题就解决了, 开发


插件也更方便了.

[运行 Hello World]

接下来让我们快来运行一下我们的插件来测试一下,
点击菜单的run, 然后我们new一个workbench的运行配置,


我们运行插件可不是普普通通的java application 就能搞定的哦,因为插
件和eclipse平
台是一根绳上的蚂蚱,谁也少不了谁,所以我们只能在一个新建的工作台上


行我们的插件.
然后就直接run吧
这时你会发现又有一个eclipse跑起来了, 就是我们测试用的平台

等新的工作台启动后, 我们来看看我们插件运行的效果, 看菜单里多了一
个sample
menu
我们点击sample menu -> sample action, 会弹出一个对话框, 写着 
Hello, Eclipse
World!

这就说明我们的插件已经成功运行了, 呵呵, 鼓掌~~
, 怎么样啊, 有成就感吧, 比那个xx lomobz用起来简单多了,哈哈


[分析 Hello World]


那接下来我们要好好分析一下前面神奇的过程了.
其实,学习插件一开始,我们就要学会怎么编写plugin.xml,因为一切的神奇
都是从这里开

我们双击plugin.xml这个文件,然后会出现一个多页编辑器,这个编辑器是
pde提供用来开
发plugin而设计的
我们先跳过这个编辑器的功能,直接这个编辑器的source页,我们就可以pl
ugin.xml的原
貌了,我们来一点一点介绍这个东东:

---------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
 // xml 的头, 不用care的

//接下来,我们要定义一个插件, 定义一个插件是有几个属性值
//id 是plugin的唯一身份标识
//name 是plugin的名字
//version 是这个插件的版本, 1.0.0 主版本.次版本.小版本
//一般来说, 插件的功能有革命性变化, 可以升主版本
//插件的功能上有些增加,就可以升次版本
//对于插件的bug的fix后,就可以升小版本
//provider-name 表明是谁做的,你可以把你的大名写上去,呵呵
//class 是这个插件的主类, 都是一些helper方法
<plugin
   id="MyPlugin"
   name="MyPlugin Plug-in"
   version="1.0.0"
   provider-name=""
   class="MyPlugin.MyPluginPlugin">

//这个是运行时的包, 我们src目录下编写的那些东东,在发布成插件时,要
打成这个jar
//这样插件运行的时候,就可以找到这些类
   <runtime>
      <library name="MyPlugin.jar"/>
   </runtime>

//插件是互相依赖的,如果你要用到其他插件,
//那你要在requires里面声明, 这样等于是把这个插件的classpath给设好

//要不然运行的时候,会找不要其他插件的这些运行库的
   <requires>
      <import plugin="org.eclipse.core.resources"/&
gt;
      <import plugin="org.eclipse.ui"/>
   </requires>


//这个是extension是eclipse最有特色的一个概念
//你可以把这个extension认为是eclipse提供的插座
//有了它我们就可以无限制的扩展我们的eclipse
//比如这里org.eclipse.ui这个插件提供了一个extension
//这个extension叫做org.eclipse.ui.actionSets
   <extension
         point="org.eclipse.ui.actionSets">

      <actionSet
            label="Sample Action Set"
            visible="true"
            id="MyPlugin.actionSet">

//我们先定义了一个menu, 叫做Sample Menu,就是我们运行的时候看到的

         <menu
               label="Sample &amp;Menu"
               id="sampleMenu">
            <separator
                  name="sampleGroup">
            </separator>
         </menu>

//在定义一个action,叫做Sample Action,
//menubarpath定义了这个action放在菜单哪个位置
//toolbar定义了这个action放在工具栏的哪个位置
//class是这个action的实现

         <action
               label="&amp;Sample Action"
               icon="icons/sample.gif"
               class="MyPlugin.actions.SampleAction"
               tooltip="Hello, Eclipse world"
               menubarPath="sampleMenu/sampleGroup"
               toolbarPath="sampleGroup"
               id="MyPlugin.actions.SampleAction">

         </action>
      </actionSet>
   </extension>

//这里又是一个extension
//作用就是让resource透视图默认打开时,
//前面定义的这个actionset可视的
//否则你还有自己customize perspective才能把这个menu显示出来
   <extension
         point="org.eclipse.ui.perspectiveExtensions"&
gt;
      <perspectiveExtension
            targetID="org.eclipse.ui.resourcePerspective&qu
ot;>
         <actionSet
               id="MyPlugin.actionSet">
         </actionSet>
      </perspectiveExtension>
   </extension>

</plugin>
----------------------------------

接下来,我们再看一下,这个action是怎么实现的

----------------------------------
//这个action类必须实现IWorkbenchWindowActionDelegate接口
public class SampleAction implements IWorkbenchWindowActionDeleg
ate {
    private IWorkbenchWindow window;

    public SampleAction() {
    }

    //这里就是action执行的实现函数
    public void run(IAction action) {
        //当action执行, 就打开一个messagedialog
                //dialog上显示hello,eclipse world!
                //这个dialog是封装在jface插件下的
                //照理说这个插件就应该需要jface插件的支持
                //不过这个插件依赖的是org.eclipse.ui这个插件
                //而ui找个插件有依赖jface,swt等插件
                //所以是嵌套依赖的
        MessageDialog.openInformation(
            window.getShell(),
            "MyPlugin Plug-in",
            "Hello, Eclipse world");
    }

    ......
}

[extension 模式]

在分析hello world中, extension这个东西,也是eclipse里面设计的神奇
之处

而提供extension的也是插件, 定义这些extension的结构, 我们叫它们为
extension
point

你可以把extension point想为接口, 而我们扩展这些extension,其实就是
实现了这个接


让我们来画个图,解释一下:
----------------------            --------------------
|plugin A            |            |plugin B          |
|   ---------------  | contibute  |  --------------  |
|   | ext point p | <--------------- | extension  |  |
|   ---------------  |_           |  --------------  |
|         ||         | |          |        ||        |
|   ---------------  | |implement |  --------------  |
|   | interface I | <--|------------ | class  C   |  |
|   ---------------  | |          |  --------------  |
---------------------- |          ----------/ -------
                       |  create, call       |
                       ----------------------|


假设plugin A定义了一个extension point, 在hello world 中就像org.e
clipse.ui定义
了一个actionsets的extension point

假设plugin B定义了一个extension,是基于plugin A的这个extension po
int的,它的实
现类是class C,就想 hello world中的那个action

那eclipse启动后, 会读取每个plugin的配置plugin.xml,然后发现plugin
 B有一个基于e
xt point p的扩展

那它就会用interface I作为对象, 然后实例化一个class C, 就等于实现
了这个extensi
on


让我们来看一段eclipse的内部实现

IPluginRegistry registry = Platform.getPluginRegistry();
IExtensionPoint extensionPoint = registry.getExtensionPoint(xpid
);
IExtension[] extensions = extensionPoint.getExtensions();
// For each extension ...
for (int i = 0; i < extensions.length; i++) {
    IExtension extension = extensions[i];
    IConfigurationElement[] elements = extension.getConfiguratio
nElements();
    ……
}


我们可以发现,eclipse就是注册每一个extension和extension point
然后用extension point来实例化它对应的那个extension


个重要概念就是extension
当然以后自己做插件也可以自己做extension point,我想以后我们会谈到
, 今天就这样




========== * * * * * ==========
返回