【原创】实现项目特性插件(二十)

上一篇 / 下一篇  2008-07-10 08:34:22 / 个人分类:Eclipse插件开发

实现项目特性插件

本节将从一个具体的实例出发,在Eclipse项目中添加用户自己的项目特性,扩展Eclipse的选项,让用户的插件具有一个产品的雏形。

项目扩展点

用户已经了解了如何在Eclipse中添加视图、编辑器、透视图菜单和工具栏按钮。本节将要介绍如何加入自己的项目相关特性,其中包括向导、项目特性、构建器和属性页。项目特性扩展点如图1所示。ITPUB个人空间z,H1m9t(R6~V }
 ITPUB个人空间%i!{)^5~Arl`k

图1  项目特性扩展点

项目特性扩展点及实现类

“nature”为用户添加项目的特有特性,Eclipse中一个项目可以同时具有多个nature特性。例如用户要在Java项目的基础上扩展自己的项目,加入了自己项目的特有特性。这样JDT就能认识用户新建的项目,用户也可以判断此Java项目是否是自己的扩展。一般来说,用户期望用到JDT的强大功能,就要使自己的项目从Java项目扩展过来。

在插件中添加nature扩展点,步骤如下。

1.  在插件清单文件的Extensions页中添加“org.eclipse.core.resources.natures”扩展点,设置ID属性为“helloworldnature”。

2.  在“org.eclipse.core.resources.natures”节点下添加runtime子节点。

3.  在runtime节点下添加run节点,设置实现类class为“com.free.project. HelloWorldNature”。
%[Ez&B3v1Xw0扩展点在plugin.xml文件中的描述如下。

<extension
se}T)r#sW0      id="helloworldnature"ITPUB个人空间4}(},a_S(h{ p
      point="org.eclipse.core.resources.natures">ITPUB个人空间2I:@ KW'Zd
   <runtime>ITPUB个人空间$M$C'd`k
      <run class="com.free.project.HelloWorldNature"/>
)f/B;V2c(x0   </runtime>
#r,I2|krbS:acv0</extension>

nature扩展点的实现类要实现“IProjectNature”接口,并要实现“IProjectNature”的如下几个方法。

setProject(IProject project):在nature类中保存当前项目。

getProject():从nature中得到当前项目。

configure():当nature被添加到项目中时,通过configure方法配置当前项目。ITPUB个人空间!Zb?F3c4F`
deconfigure():当nature从项目删除时,通过deconfigure方法删除相应配置。ITPUB个人空间Sm9u#f4k
nature对应的实现类为“HelloWorldNature”,在此实现类中主要功能是通过configure方法配置当前项目的构建器,代码如例程1所示。

例程1  HelloWorldNature.java
qz B-s%Gli0h ^h0public class HelloWorldNature implements IProjectNature {

    private IProject _project;ITPUB个人空间a;E?o']"h4VB
    //配置NatureITPUB个人空间w/US!o1k5v;C A
    public void configure() throws CoreException {ITPUB个人空间UM$n(x J;om4R
     System.out.println("configure");
Qy9V6Aif&Z-CXy0        IProjectDescription projectDesc = _project.getDescription();ITPUB个人空间&a YP.AE(T/R+AJ
        ICommand[] buildSpec = projectDesc.getBuildSpec();ITPUB个人空间f!yWu0u'l|
        boolean hasBuilder = false;ITPUB个人空间Z:DG:ws_u OF
        //遍历项目的构建器
K J#QCf EV'p"P&F0        for (int i = 0; i < buildSpec.length; ++i) {ITPUB个人空间5~^3l'GQrn'M
                   if (buildSpec[i]
%Z V-Z R2g Tg:I0                .getBuilderName()
fw k$Ti4Z#Nq0                .equals("com.free.proj.helloproject.helloworldbuilder")) {
A*w*\2^1O_.\0                hasBuilder = true;ITPUB个人空间D}.p d8d"zX
                System.out.println("true");ITPUB个人空间f}y[$l2?
                break;ITPUB个人空间Mr.TqB
            }ITPUB个人空间M u6b \%T0O8r$M
        }

        if (hasBuilder == false) {ITPUB个人空间x&@!?*Q(E?i0B"V4V
         System.out.println("false");ITPUB个人空间"kAQ5K q'_ }^
            ICommand newCommand = projectDesc.newCommand();
fPA$y){N0            newCommand.setBuilderName("com.free.proj.helloproject.helloworldbuilder");
fEeTAe0            ICommand[] buildSpecs = new ICommand[buildSpec.length + 1];

            System.arraycopy(buildSpec, 0, buildSpecs, 1, buildSpec.length);ITPUB个人空间r4\s%ND9N
            buildSpecs[0] = newCommand;
UwGW t0            projectDesc.setBuildSpec(buildSpecs);ITPUB个人空间 uZz3V@|F
            _project.setDescription(projectDesc, null);
3`W0j5i}m7z0        }
:kd I%`4[zo0    }

    public void deconfigure() throws CoreException {ITPUB个人空间f\_.|4_3v
      ITPUB个人空间1S~+U+u |:S:y"J
    }ITPUB个人空间Z)yd7~a _3Gm
    //获得Nature所关联的项目
;HJ-Nq.tQOv0    public IProject getProject() {ITPUB个人空间 s1Q"rL1D!WA^ Ua b
     System.out.println("getProject");ITPUB个人空间%H'M0h%|Gu*W+oj({
               return _project;ITPUB个人空间!g ukb S Nmm3uu
    }
$y1|cvV^n$he0   //设置Nature所关联的项目ITPUB个人空间_p:b+b%S e*h-TR|
    public void setProject(IProject project) {ITPUB个人空间 F6O| yB#x } x
      System.out.println("setProject");
d&sQ)O ZV1B s}2H4W0      _project = project;
/F#bn]j5Y~Fp-I}j0    }

}

提示:此外构建器的ID号为“com.free.proj.helloproject.helloworldbuilder”,ID号为插件ID号加构建器ID号,在Eclipse中和产品及项目相关的ID都采用这种方式。

构建器扩展点及实现类

Builder为项目的构建器,通过构建器能实现项目的增量构建和完全构建。在插件中添加Builder扩展点,步骤如下。

1.  在插件清单文件的Extensions页中添加“org.eclipse.core.resources.builders”扩展点,设置ID属性为“helloworldbuilder”,name属性为“hello world, bulder”。

2.  在“org.eclipse.core.resources.builders”节点下添加builder子节点。

3.  在builder节点下添加run节点,设置实现类class为“com.free.project. HelloWorldBuilder”。ITPUB个人空间 s&JJ _7`-{&x+f
扩展点在plugin.xml文件中的描述如下。

<extensionITPUB个人空间DS)ZMp5v)l v U
         id="helloworldbuilder" name="hello world, bulder"
0` M-o;T5{ _}~)w2C"nd0         point="org.eclipse.core.resources.builders">ITPUB个人空间tyWPs N#\
      <builder>
,U'IJ'm3^[5f\*a0         <run class="com.free.project.HelloWorldBuilder"/>ITPUB个人空间(kIW2HJ$Vn`7\
      </builder>ITPUB个人空间;a I5`\*a!D!?
   </extension>

builder扩展点的实现类继承于“IncrementalProjectBuilder”类,并实现了两个资源监听器。当项目中资源发生变化的时候调用构建,本例中只打印出相应的数据,并没有实现构建的动作,当用户需要构建时可以替换相应代码,例如编译文件等。代码如例程2所示。

例程2  HelloWorldBuilder.java
4e2V/xz/[}0public class HelloWorldBuilder extends IncrementalProjectBuilder {
8LSi+wW$m0    //实现资源监听器ITPUB个人空间8mpGm:Ru)\9D
    private class HelloWorldVisitor implements IResourceVisitor {
;t9c3EH'e} p0        public boolean visit(IResource resource) throws CoreException {ITPUB个人空间dh H+B-Fa"W
            System.out.println("**** HelloWorldVisitor.visit() ****");ITPUB个人空间NUNVT-R'KZv
            switch (resource.getType()) {
&`@A LF:_qO&_0            case IResource.PROJECT:
*]3|(P;z(w&Np,K0                System.out.println("Project added: " + resource.getName());ITPUB个人空间Z:m6`2GWld
                break;
#o.?A!D"Mw:Grg*B0            case IResource.FOLDER:
+A1Brz.if:} NS0                System.out.println("Folder added: " + resource.getName());ITPUB个人空间*`*v vJN q3i~[
                break;
@{1KrAE U0            case IResource.FILE:
$V/BzV ~ DQM0                System.out.println("File added: " + resource.getName());ITPUB个人空间1Z#X"q#Sy5?E0E \a
                break;
%S[&ko'U2tg5H0            }

            return true;
b\6V c#e"yq(T g%K6O0        }
D:O1_"E3bM"_0    }
5z"~[#~|&_.q,TLl6w n0    //实现资源监听器
Qm_r#MfS0    private class HelloWorldDeltaVisitor implements IResourceDeltaVisitor {ITPUB个人空间u3u"L8Q!J2u&X(Q!E
        public boolean visit(IResourceDelta delta) throws CoreException {ITPUB个人空间tf J R&p
            System.out.println("**** HelloWorldDeltaVisitor.visit() ****");ITPUB个人空间7|?4a~o@.xH
            String type = null;ITPUB个人空间i.Y z:u Sd!\`,g^
            switch (delta.getResource().getType()) {
}4S#R~7s#N c0            case IResource.ROOT:ITPUB个人空间']} SSzb `
                type = "ROOT";
l\x+|;~ F#X9g&S0                break;
PSj$ktZ[0hU0            case IResource.PROJECT:
+}~#sf.^ed0                type = "Project";
7U?%a6pm|0                break;
fN,TbY/W9D|"d0            case IResource.FOLDER:
omT5{3p0                type = "Folder";ITPUB个人空间Od3[7m%du^0n
                break;
:E?QJ!X1i `*K0            case IResource.FILE:ITPUB个人空间Ew6t*p1_!f o
                type = "File";
"xq,H7iQ1j(W*Ml w0                break;
^G0h-qqL6v2P5u0            }

            switch (delta.getKind()) {ITPUB个人空间6I6O1@__[4NqCI-w
            case IResourceDelta.ADDED:ITPUB个人空间+qX\AFNOwo6[
                System.out.println(type + " added: "+ delta.getResource().getName());
1y.U#?f7r0VTc2B*~Bh-Q0                break;
0TS @!^X5?![b0            case IResourceDelta.CHANGED:
;w z(U;xU^5b0                System.out.println(type + " changed: "ITPUB个人空间K jp!U)CF9{ V
                        + delta.getResource().getName());ITPUB个人空间t5i.O(x;\q[ `
                break;ITPUB个人空间1AkYM7G
            case IResourceDelta.REMOVED:ITPUB个人空间.L y6DR`Ou,O:r
                System.out.println(type + " removed: "
4fG;F8j2[[*I&H0                        + delta.getResource().getName());
+O bc p/e;g&Ml/X#m0                break;
SGE7Y2v(Xf{0            }

            return true;ITPUB个人空间:Z'j:|1dV:G;a
        }
"Nu!?$x&hcF G0    }

    public HelloWorldBuilder() {ITPUB个人空间h+_7A:W2Bz
        System.out.println("HelloWorldBuilder.constructor()");
C _;Q-xh0    }
5x)Qh7APgx7g0    //开始构建
_ L${L~ l;AGl2P's0    protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
3l0d:`,T7Q}0            throws CoreException {
i+L-H}j A0        System.out.println("HelloWorldBuilder.build()");
O(V%i'r?q6ua;j@-O,a E0        //当构建类型不同时,添加不同的资源监听器
-d z-A-rD(pLv:D2p-o.H0        if (kind == IncrementalProjectBuilder.FULL_BUILD) {ITPUB个人空间Y u3bb}^j
            System.out.println("FULL_BUILD");ITPUB个人空间 I)tg7wD1G,dcUw
            getProject().accept(new HelloWorldVisitor());
S"e4C i`^k ?H0        } else {ITPUB个人空间 M"JR6~"@
            IResourceDelta delta = getDelta(getProject());
5dO2P-q L2b0            if (delta == null) {
(k}-H?)v^m6Q;i0                System.out.println("AUTO_BUILD");ITPUB个人空间{#}]2{yP
                getProject().accept(new HelloWorldVisitor());ITPUB个人空间"E3A$t~oB9?9U3Z
            } else {ITPUB个人空间6p*_c Z3J `,f$T ]
                System.out.println("INCREMENTAL_BUILD");ITPUB个人空间,nkn O#L&d
                delta.accept(new HelloWorldDeltaVisitor());
-TMG/\1PBcvF0            }ITPUB个人空间N]q%j/d wK
        }
YN~e+~G0        return null;
7w5}X2k;X |0    }

}
%P)O1B&gX4~j0在用户建立的项目中,如果资源发生改变,builder会调用“HelloWorldDeltaVisitor”类进行增量构建处理,当清除项目时会调用“HelloWorldVisitor”类进行完全构建处理。插件运行后,当用户选择自定义项目时,用户可以打开项目属性窗口看到“hello world, builder”构建器,如图2所示。
~$p'V5Q1r0 
F tk/z^ g.R\pp;}0

图2  项目属性窗口

工程向导扩展点及实现类

用户如果要在项目中添加自定义的资源,采用Eclipse中的向导是最好的方式。项目也是资源的一种,一般来说如果对新建的资源有输入条件的要求,都采用向导的方式。例如新建Java项目,要输入项目名称和构建路径等。在插件中添加newWizard扩展点,步骤如下。

1.  在插件清单文件的Extensions页中添加“org.eclipse.ui.newWizards”扩展点。ITPUB个人空间F4b7N-z)p?lr9f
2.  在“org.eclipse.ui.newWizards”节点下添加category子节点,设置ID属性为“com.free.project.wizard.category”,name属性为“HelloWorld Project Category”。
8BfD"T R\ `03.  在“org.eclipse.ui.newWizards”节点下添加wizard节点,设置实现类class为“com.free.project.HelloWorldWizard”,ID属性为“com.free.project.wizard”。

扩展点在plugin.xml文件中的描述如下:
e~2d&R.f8u|;W,o;y9O0<extensionITPUB个人空间&M^k7X c
         point="org.eclipse.ui.newWizards">ITPUB个人空间l ~1KcZ {
      <categoryITPUB个人空间)X4t0qM8zh2ry
            name="HelloWorld  Project Category"
RM)gy fNe`0I&f0            id="com.free.project.wizard.category"/>
5@(K nJz0      <wizardITPUB个人空间5Y!Q;H,h'e^2_
            class="com.free.project.HelloWorldWizard"
(m)A:{1qo Z+HS0            category="com.free.project.wizard.category"ITPUB个人空间W\ X2r'{bP
            name="HelloWorld Project Wizard"ITPUB个人空间 J+D&YB?6uA
            id="com.free.project.wizard"/>ITPUB个人空间 AJ6q H.T(g
</extension>

newWizards扩展点的实现类继承于“org.eclipse.jface.wizard.Wizard”类,并实现了“org.eclipse.ui.INewWizard”接口。在实现类中,通过addPages方法添加向导页到当前向导,通过performFinish方法完成向导的结束。实现类“HelloWorldWizard”的代码如例程3所示。

例程3  HelloWorldWizard.java
U4VjKBS2vl|"s0public class HelloWorldWizard extends Wizard implements INewWizard {

    private WizardNewProjectCreationPage _page;

    public HelloWorldWizard() {ITPUB个人空间 fR\+U`g2O s
        super();
mp G(U_Z)Q0    }ITPUB个人空间Q\D0c]+@m
    //添加向导页ITPUB个人空间1P dX#S6z
    public void addPages() {ITPUB个人空间&ebF|!X)}
        _page = new WizardNewProjectCreationPage("page1");
xs+MBH2{[~!p0        _page.setDescription("Page 1 of Helloworld New Wizard");ITPUB个人空间FvoM9kuc M@
        _page.setTitle("HelloWorld Wizard");
e AC*K}*s)PV'wg$O`!a0        addPage(_page);ITPUB个人空间[3?8a4u+|)E5G)c-T
    }
)q]0A'iX:K]s@V0    //完成向导ITPUB个人空间-D#[N1i%u]5k+f wO D*U
    public boolean performFinish() {ITPUB个人空间9N+oWz*D;p
        boolean result = false;

        System.out.println("project page.name = " + _page.getProjectName());
q4|l1HU}3V0        System.out.println("project page.path = " + _page.getLocationPath());
k7}!B6Y,Ly9N6_)u%[0        IProject project = _page.getProjectHandle();
v#Jh6[%X\ j;De0        try {
^~-B9o%x0            project.create(null);
8o#~YSf7M.HA0            result = true;ITPUB个人空间q0|0J}l n)a [
        } catch (CoreException e) {
g+^a/t8uYn0            e.printStackTrace();
\@+j!Q-^1YRx!k0        }

        IProjectDescription projectDesc = null;ITPUB个人空间t*q0L5s#o7Q\2mG
        try {
b(l-O$v,_0            project.open(null);ITPUB个人空间5cz ]`a{
            projectDesc = project.getDescription();
"K^3hM,g#{u_l0        } catch (CoreException e1) {
pee0M+wj3]C0            e1.printStackTrace();ITPUB个人空间(Gk1P/Q:e1c8_ lK
        }

        String[] natureIds = projectDesc.getNatureIds();
T)a/MKPaTTN0        String[] newNatureIds = new String[natureIds.length + 1];
9Lk&E$j^~ S0        System.arraycopy(natureIds, 0, newNatureIds, 0, natureIds.length);
N!U k*dK9wzD0        newNatureIds[natureIds.length] = "com.free.proj.helloproject.helloworldnature";ITPUB个人空间~-KRYV
        projectDesc.setNatureIds(newNatureIds);ITPUB个人空间5eU%{AN{U
        try {
]8|\!H%z/u@0            project.setDescription(projectDesc, null);ITPUB个人空间f,s]`L tV
        } catch (CoreException e2) {ITPUB个人空间%w.Jz8H4v*x!IK
            e2.printStackTrace();ITPUB个人空间.aQ KT)P["@0}j u
        }

        return result;ITPUB个人空间6I0P}5UO&u*|r
    }

    public void init(IWorkbench workbench, IStructuredSelection selection) {
;@'F)C0j)~&W*P(b0      ITPUB个人空间9m`:J.L8s px
    }

}

本例程中没有实现用户定义的向导页,而是用Eclipse下的“WizardNewProjectCreationPage”页来作为向导页。用户也可以定义向导页,如果有兴趣可以参考多页签编辑器中的例子源代码,多页签编辑器插件已经实现了向导。本例中可以通过新建菜单新建用户定义的项目,向导对话框如图3所示。
7NM`l4lC0 
(GvEu]Q0

图3  向导对话框

首选项页扩展点及实现类

在用户定义的项目中,一般都会有相应的参数配制。例如说Tomcat要配置相应的Web服务器,JDT可以配置代码的风格、JDK和JRE等。在插件中可以添加preferencePages扩展点,实现项目参数的配置,步骤如下。

1.  在插件清单文件的Extensions页中添加“org.eclipse.ui.preferencePages”扩展点。
Z BdC'U)^~Nj02.  在“org.eclipse.ui.preferencePages”节点下添加page子节点,设置节点的ID属性为“com.free.project.page”,name属性为“HelloWorld”,class属性为“com.free.project.Workbench- PreferencePage”。
2?|:^ Bz%j Nmb0扩展点在plugin.xml文件中的描述如下。

<extension
S u8u.p3n]0    point="org.eclipse.ui.preferencePages">ITPUB个人空间3A h[ U$BI fq`c'K#?
 <page
;UPF9Q6l&OOw0       class="com.free.project.WorkbenchPreferencePage"
e,xB#rPM0       name="HelloWorld"ITPUB个人空间/R A)|6JnA*}S&w
       id="com.free.project.page"/>ITPUB个人空间 fG0da?:C9S,w
</extension>

preferencePages扩展点的实现类继承于“org.eclipse.jface.preference.PreferencePage”类,并实现了“org.eclipse.ui.IWorkbenchPreferencePage”接口。在实现类中,通过createContents方法构建自己的属性页,通过performOk方法完成向导的结束。实现类“WorkbenchPreferencePage”的代码如例程4所示。

例程4  WorkbenchPreferencePage.java
5@oHN+|&?0public class WorkbenchPreferencePage extends PreferencePage implementsITPUB个人空间 d Q;b z/?;]S
        IWorkbenchPreferencePage {

    private Text _greeting;

    public WorkbenchPreferencePage() {
(aw`0~M5C0        super();
L`,}4D J}0    }

    public WorkbenchPreferencePage(String title) {ITPUB个人空间,A KLdsv)p(~
        super(title);
%?7u4U2lw&t1KP0    }

    public WorkbenchPreferencePage(String title, ImageDescriptor image) {
t0anah^0        super(title, image);ITPUB个人空间;Z5d\(s+_n
    }

    protected Control createContents(Composite parent) {ITPUB个人空间vZ V)YI m
        Label label = new Label(parent, SWT.CENTER);ITPUB个人空间 J[DKs
        label.setText("Greeting");ITPUB个人空间FXe'l)C)pH6J|
        _greeting = new Text(parent, SWT.SINGLE | SWT.BORDER);

        return parent;ITPUB个人空间*?4?W0]VDq&u
    }

    protected IPreferenceStore doGetPreferenceStore() {ITPUB个人空间 h ~w1o r[W4`&_
        System.out.println("WorkbenchPreferencePage.doGetPreferenceStore()");ITPUB个人空间+s,|FiQoJ#} hy w
        return HelloWorldPlugin.getDefault().getPreferenceStore();ITPUB个人空间 BA6eit/j1xUj
    }

    public void init(IWorkbench workbench) {
{ x"d M*c |#rFE:x{Af0   ITPUB个人空间b0k%\uUZ
    }

    protected void performDefaults() {
UT?J0_PX`0        System.out.println("WorkbenchPreferencePage.performDefaults()");
WH ~e;H M0        IPreferenceStore prefStore = getPreferenceStore();ITPUB个人空间ZF.G2R6]$I0}
        prefStore.setValue(HelloWorldPlugin.GREETING, "world");ITPUB个人空间6Jfj)_T_
        HelloWorldPlugin.getDefault().savePluginPreferences();

        _greeting.setText(prefStore.getString(HelloWorldPlugin.GREETING));ITPUB个人空间p C5Ad.z:M
    }

    public boolean performOk() {ITPUB个人空间,ly4q'I[:Z1`3M
        boolean result = false;

        System.out.println("WorkbenchPreferencePage.performOk()");
}9ct2f1Yf;^0y0        IPreferenceStore prefStore = getPreferenceStore();ITPUB个人空间+d{ E+w.I g CU
        prefStore.setValue(HelloWorldPlugin.GREETING, _greeting.getText());
m uH*Ouu0        HelloWorldPlugin.getDefault().savePluginPreferences();

        result = true;

        return result;
D8P-a*x'N1e'}0    }
2b^%U sB0}

本例程只添加了一个Label控件和一个Text控件。若用户有兴趣可以添加自己完成的属性页,选择“window”→“preferences”菜单,打开首选项对话框,程序运行效果如图4所示。
W*L8W],}0 ITPUB个人空间*Nq({0y2c5R3|p

图4  首选项窗口

提示:在Eclipse中,首选项页中定义的信息是一个全局的信息,这些信息为Workspace中所有的工程所共享,而属性页(property page)中的信息为某一个资源所独有,例如工程的属性。

下载(com.free.proj.helloproject.rar)
\s^{~+y0


TAG: eclipse java

引用 删除 Guest   /   2009-03-18 11:07:36
5
引用 删除 elvaelva1232003   /   2008-07-25 11:04:21
5
引用 删除 Guest   /   2008-07-10 09:06:26
不错,很详细
 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2009-07-05  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 21593
  • 日志数: 43
  • 文件数: 11
  • 建立时间: 2008-02-14
  • 更新时间: 2008-09-05

RSS订阅

Open Toolbar