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

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

实现项目特性插件

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

项目扩展点

用户已经了解了如何在Eclipse中添加视图、编辑器、透视图菜单和工具栏按钮。本节将要介绍如何加入自己的项目相关特性,其中包括向导、项目特性、构建器和属性页。项目特性扩展点如图1所示。ITPUB个人空间P4~0YL,i"Yh \
 ITPUB个人空间 Yt?1BW2s/E

图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”。ITPUB个人空间!F u0w U{%j']-A&]
扩展点在plugin.xml文件中的描述如下。

<extensionITPUB个人空间t+E"awA\'KQO%g
      id="helloworldnature"
/{s0lA I0      point="org.eclipse.core.resources.natures">ITPUB个人空间;I SK1l0da|
   <runtime>ITPUB个人空间|(z1wB2X%}s4X
      <run class="com.free.project.HelloWorldNature"/>ITPUB个人空间 vha5J$L+e |?/P
   </runtime>
f6g KZO-S%?0K0</extension>

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

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

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

configure():当nature被添加到项目中时,通过configure方法配置当前项目。
X"rE r![;lH0deconfigure():当nature从项目删除时,通过deconfigure方法删除相应配置。ITPUB个人空间(Tm.U2`"S|
nature对应的实现类为“HelloWorldNature”,在此实现类中主要功能是通过configure方法配置当前项目的构建器,代码如例程1所示。

例程1  HelloWorldNature.java
??R:U*gVr1z,u;Kc0public class HelloWorldNature implements IProjectNature {

    private IProject _project;ITPUB个人空间`dD7p|"CP
    //配置NatureITPUB个人空间)].Qo ]3hNu,m
    public void configure() throws CoreException {ITPUB个人空间;R v2pfBi7E3f
     System.out.println("configure");ITPUB个人空间 ^NGk:M
        IProjectDescription projectDesc = _project.getDescription();
2k([8n oTpD6O$M0        ICommand[] buildSpec = projectDesc.getBuildSpec();ITPUB个人空间;fz1o#hz
        boolean hasBuilder = false;
b2D:?.c_5w/K X#w6e4]0        //遍历项目的构建器ITPUB个人空间1w L'Sr ih_ ?TY
        for (int i = 0; i < buildSpec.length; ++i) {ITPUB个人空间H!]5nl~:g,G#W
                   if (buildSpec[i]
UB[H h1f7Q+k0                .getBuilderName()
jC ^7jc%E!mTL0                .equals("com.free.proj.helloproject.helloworldbuilder")) {ITPUB个人空间 `j^l$mE xV|q)z.[
                hasBuilder = true;
0xPFf)y[$~lj0                System.out.println("true");ITPUB个人空间s5K8l;ePc]]h
                break;
\6\!mt6^0uoa0            }ITPUB个人空间.t%l-]O#J7q
        }

        if (hasBuilder == false) {
8f mO'o Q4h~0         System.out.println("false");ITPUB个人空间5G!_)VDs3N b
            ICommand newCommand = projectDesc.newCommand();
9r I P2N7C'}0            newCommand.setBuilderName("com.free.proj.helloproject.helloworldbuilder");ITPUB个人空间 `%pU{ U+d#F
            ICommand[] buildSpecs = new ICommand[buildSpec.length + 1];

            System.arraycopy(buildSpec, 0, buildSpecs, 1, buildSpec.length);ITPUB个人空间lT(D[2Asgl;H6V
            buildSpecs[0] = newCommand;ITPUB个人空间"k4`V;fFTr:w0h
            projectDesc.setBuildSpec(buildSpecs);
#Ux:LUE0            _project.setDescription(projectDesc, null);
keP"r9YW6Np;h0        }
P7DD8n%P)g.P M0    }

    public void deconfigure() throws CoreException {
'K*M rON M0      
0|`1FV%m5T ^gP9B0    }ITPUB个人空间9`;@ cqNq6TR
    //获得Nature所关联的项目ITPUB个人空间$k8WF Z mf'Mt Z;L6m
    public IProject getProject() {
n*O J5e wL4_H)|tJ0     System.out.println("getProject");ITPUB个人空间t~ }u}$g
               return _project;ITPUB个人空间)z2H*OyF/g
    }ITPUB个人空间2`_E&X:~Mi3`1V,L-S(j3S
   //设置Nature所关联的项目
8A^x5UU|*Od0E0    public void setProject(IProject project) {ITPUB个人空间vr,b(NJ?"|a.S
      System.out.println("setProject");ITPUB个人空间J wg c)l:ft4f
      _project = project;ITPUB个人空间DG)m{hP-O
    }

}

提示:此外构建器的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个人空间-qt;})QN-Owa
扩展点在plugin.xml文件中的描述如下。

<extensionITPUB个人空间^~ Jx,d0@
         id="helloworldbuilder" name="hello world, bulder"ITPUB个人空间U R3`/KkV(b!kv
         point="org.eclipse.core.resources.builders">ITPUB个人空间F%@1NrN^9^&I P$j
      <builder>
)H5K:`8N |rv;q0         <run class="com.free.project.HelloWorldBuilder"/>ITPUB个人空间P ]boKk'p7lvG
      </builder>
bz"Lu g2}*Q0   </extension>

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

例程2  HelloWorldBuilder.javaITPUB个人空间z-t(K4jg*cq
public class HelloWorldBuilder extends IncrementalProjectBuilder {
6m"qir*q'cz0    //实现资源监听器
E'c0RPbE0    private class HelloWorldVisitor implements IResourceVisitor {ITPUB个人空间YEkC F0H$X:T
        public boolean visit(IResource resource) throws CoreException {ITPUB个人空间$z9r/]"C5y3|*Zw `G3A
            System.out.println("**** HelloWorldVisitor.visit() ****");ITPUB个人空间*[)W4E,Z0c;h[3[
            switch (resource.getType()) {
sk*}t s0f0            case IResource.PROJECT:
F-sX&IR0                System.out.println("Project added: " + resource.getName());
6UB+x&a*j6n0                break;
0_ U[%sI0            case IResource.FOLDER:
nel!h%yut ^CX0                System.out.println("Folder added: " + resource.getName());ITPUB个人空间e.J?:V&a
                break;
Gt7Q+Jq ~0            case IResource.FILE:ITPUB个人空间%|7~XZB,z-udg^
                System.out.println("File added: " + resource.getName());ITPUB个人空间x EG7Ad(e+w6~/G
                break;ITPUB个人空间Pw;x4SMK
            }

            return true;
Ve.A be XW nY,Qf0        }ITPUB个人空间Zd3UKE`
    }
q?v+uz2C6H0    //实现资源监听器ITPUB个人空间 rR~/c8X,nEM`V.|
    private class HelloWorldDeltaVisitor implements IResourceDeltaVisitor {ITPUB个人空间7H6n&S}0@ ?0oE
        public boolean visit(IResourceDelta delta) throws CoreException {ITPUB个人空间-O-G/v"c5^%M
            System.out.println("**** HelloWorldDeltaVisitor.visit() ****");
%aa J5akIeW0            String type = null;
9|%Bw7_ Sp0            switch (delta.getResource().getType()) {ITPUB个人空间 x2i%fco,Fm n)y*W
            case IResource.ROOT:
DhX6o4cRU0                type = "ROOT";
3A`i8D-B]-v@.lL!b0                break;ITPUB个人空间F;nn+L%m#@Pv4q
            case IResource.PROJECT:ITPUB个人空间2QcKzb \pTD k
                type = "Project";
H$\:R"z(W'\[P0                break;
d!tar/Q }O"P0g0            case IResource.FOLDER:
&LpeJ(Q7d1v L0                type = "Folder";ITPUB个人空间$Sb,w'V%S+a.n
                break;
O DU4[B$U0            case IResource.FILE:
$z/k-] |sWA s:zn$I0                type = "File";
-A L8s5lq0                break;
*i5iSY1l'[*~0            }

            switch (delta.getKind()) {ITPUB个人空间 @)XsZ3sI:e o:s@W
            case IResourceDelta.ADDED:
;t.ag] ]0                System.out.println(type + " added: "+ delta.getResource().getName());ITPUB个人空间F2c6v9p Z/oD{
                break;ITPUB个人空间+m5e5q/j}l9kHE
            case IResourceDelta.CHANGED:
[yx#[Yi%uS {0                System.out.println(type + " changed: "ITPUB个人空间{ BTyF#i(PyxO
                        + delta.getResource().getName());ITPUB个人空间4{,K~S&W5HX
                break;ITPUB个人空间 d)d9a-BQpw,?
            case IResourceDelta.REMOVED:
{9V"K:Xa"F@ m0                System.out.println(type + " removed: "ITPUB个人空间 [ B+N6n L,? w O2qm M
                        + delta.getResource().getName());
!E,i)@-gW$?+h0                break;
+V[ QRKA0            }

            return true;
;q;t ~k"cv0        }ITPUB个人空间oy{+ah)OiI"y
    }

    public HelloWorldBuilder() {
!x4K;T T#m8E3r&\Y0        System.out.println("HelloWorldBuilder.constructor()");ITPUB个人空间;h$e0{L Z
    }
9Y8YFh$Y Y0    //开始构建
~V:Grz0    protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
[6z _"L/B*DT q0            throws CoreException {
H6Kb ]QB0        System.out.println("HelloWorldBuilder.build()");
)WC"yi'[E%s0        //当构建类型不同时,添加不同的资源监听器ITPUB个人空间 o!a/tjA&J+w
        if (kind == IncrementalProjectBuilder.FULL_BUILD) {ITPUB个人空间6}N8N#~E+qJ7d
            System.out.println("FULL_BUILD");
7y-Yk+mP7GH0            getProject().accept(new HelloWorldVisitor());
0l/Ke c ~8fo#} Y0        } else {
n*h pR P)m8i0            IResourceDelta delta = getDelta(getProject());ITPUB个人空间5n|1F,Y(U6IR,M"f
            if (delta == null) {
|Px ZeW0                System.out.println("AUTO_BUILD");
c5X)@9Q&| wN$]2D0                getProject().accept(new HelloWorldVisitor());
&E&P,|^|,Q0            } else {
-N1[NJ4NR0                System.out.println("INCREMENTAL_BUILD");
N{l^I2O4zOh-p0W0                delta.accept(new HelloWorldDeltaVisitor());ITPUB个人空间;t z*M;E!x$PKP-^o
            }ITPUB个人空间;DeyIA Nu5C
        }ITPUB个人空间`H1J)H/f Voq
        return null;ITPUB个人空间~/gOT2xQA n6d
    }

}
E [G/`W-i,~g5M0在用户建立的项目中,如果资源发生改变,builder会调用“HelloWorldDeltaVisitor”类进行增量构建处理,当清除项目时会调用“HelloWorldVisitor”类进行完全构建处理。插件运行后,当用户选择自定义项目时,用户可以打开项目属性窗口看到“hello world, builder”构建器,如图2所示。ITPUB个人空间5? D]1~)q K#[+s a n
 
;nt!~g HF!r iv0

图2  项目属性窗口

工程向导扩展点及实现类

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

1.  在插件清单文件的Extensions页中添加“org.eclipse.ui.newWizards”扩展点。ITPUB个人空间1MjZ E1b6y n0R+M/o
2.  在“org.eclipse.ui.newWizards”节点下添加category子节点,设置ID属性为“com.free.project.wizard.category”,name属性为“HelloWorld Project Category”。ITPUB个人空间jnm y0Q X~Fn|
3.  在“org.eclipse.ui.newWizards”节点下添加wizard节点,设置实现类class为“com.free.project.HelloWorldWizard”,ID属性为“com.free.project.wizard”。

扩展点在plugin.xml文件中的描述如下:
:k p_,gJn'w o0<extension
D+E._q B'GF9U0v0         point="org.eclipse.ui.newWizards">ITPUB个人空间(vFL,h Kg
      <categoryITPUB个人空间8J%GA7x)H2a z+}aY
            name="HelloWorld  Project Category"ITPUB个人空间-a/r Su3F{
            id="com.free.project.wizard.category"/>
?6[u9B-Lm!C0      <wizardITPUB个人空间HE Y%h{
            class="com.free.project.HelloWorldWizard"
w/Z(@;i)|Jg%{0            category="com.free.project.wizard.category"
$V]X$Lx0            name="HelloWorld Project Wizard"ITPUB个人空间 \q gSq xlzr
            id="com.free.project.wizard"/>ITPUB个人空间s LmXuR
</extension>

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

例程3  HelloWorldWizard.java
K aNq9O&}#r0public class HelloWorldWizard extends Wizard implements INewWizard {

    private WizardNewProjectCreationPage _page;

    public HelloWorldWizard() {
B i4qQ@0        super();ITPUB个人空间1Nkt[-d?
    }
K6q,M;Q1q4D0    //添加向导页ITPUB个人空间 J M/~~T"_^!a
    public void addPages() {ITPUB个人空间FR\:UT y
        _page = new WizardNewProjectCreationPage("page1");
C d7f6e)x+P;d3F0        _page.setDescription("Page 1 of Helloworld New Wizard");ITPUB个人空间u-V$G j!{m&H3oX
        _page.setTitle("HelloWorld Wizard");
T2b1\h+h]@'ybU0        addPage(_page);
)OW/s$_9~_$E I0    }ITPUB个人空间*v%v g{7G Ja*n
    //完成向导
0TX^!V"N'|wl0    public boolean performFinish() {ITPUB个人空间 v/j^tI/j%B8t%@ g$L[
        boolean result = false;

        System.out.println("project page.name = " + _page.getProjectName());
1F3|mm\[*Jm"s0        System.out.println("project page.path = " + _page.getLocationPath());ITPUB个人空间"g(j0WG]0Dw
        IProject project = _page.getProjectHandle();ITPUB个人空间9T,vv"] _
        try {ITPUB个人空间zL)|7T0Or
            project.create(null);ITPUB个人空间2gDr$v8b*@
            result = true;
;~Ysg!^@0        } catch (CoreException e) {
-FI'M0Py1ve0            e.printStackTrace();ITPUB个人空间)t6Wi bJ$_*y(U
        }

        IProjectDescription projectDesc = null;ITPUB个人空间4O J:M A#@,l _
        try {
G,J D:}+s|1t0            project.open(null);ITPUB个人空间8YK)~l{w)]
            projectDesc = project.getDescription();
4@jsg-J0        } catch (CoreException e1) {
Rw@/O HH`$U7r0            e1.printStackTrace();ITPUB个人空间"^ cx;H5tyy
        }

        String[] natureIds = projectDesc.getNatureIds();
2e\f7Qn#n'B%R;G0        String[] newNatureIds = new String[natureIds.length + 1];
~$?2^1K Mg9\\0        System.arraycopy(natureIds, 0, newNatureIds, 0, natureIds.length);
bO)N0[&i0        newNatureIds[natureIds.length] = "com.free.proj.helloproject.helloworldnature";ITPUB个人空间1W|W]+F;Yw
        projectDesc.setNatureIds(newNatureIds);
8b'@qj"`0        try {
/L(zX@ D%N0            project.setDescription(projectDesc, null);
4kd.t1o MP2_W_A0        } catch (CoreException e2) {
2K3c`Lok s)d0            e2.printStackTrace();ITPUB个人空间T6xMM{
        }

        return result;ITPUB个人空间 e8E!Iv^.v&GE9Y
    }

    public void init(IWorkbench workbench, IStructuredSelection selection) {
M-oH"t(e'EV7\0      
.Ro/kMq0    }

}

本例程中没有实现用户定义的向导页,而是用Eclipse下的“WizardNewProjectCreationPage”页来作为向导页。用户也可以定义向导页,如果有兴趣可以参考多页签编辑器中的例子源代码,多页签编辑器插件已经实现了向导。本例中可以通过新建菜单新建用户定义的项目,向导对话框如图3所示。ITPUB个人空间$Xj;O/ri7ep(|
 ITPUB个人空间!F5b4R| r

图3  向导对话框

首选项页扩展点及实现类

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

1.  在插件清单文件的Extensions页中添加“org.eclipse.ui.preferencePages”扩展点。
i&|"o%a"i2H02.  在“org.eclipse.ui.preferencePages”节点下添加page子节点,设置节点的ID属性为“com.free.project.page”,name属性为“HelloWorld”,class属性为“com.free.project.Workbench- PreferencePage”。
8Ia\pvSApTd0扩展点在plugin.xml文件中的描述如下。

<extensionITPUB个人空间0Q!H8d-wh+Yg
    point="org.eclipse.ui.preferencePages">ITPUB个人空间)x$T;\ o1B:`7T;IR
 <pageITPUB个人空间^1|yO*h F
       class="com.free.project.WorkbenchPreferencePage"
ftk&oh"WM0       name="HelloWorld"ITPUB个人空间ES?'ax,X,Lf)YL
       id="com.free.project.page"/>ITPUB个人空间-VXD{,U3Hj?
</extension>

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

例程4  WorkbenchPreferencePage.javaITPUB个人空间tbh;D0Y ?6Ll:f
public class WorkbenchPreferencePage extends PreferencePage implementsITPUB个人空间fSoeZJ:Sg
        IWorkbenchPreferencePage {

    private Text _greeting;

    public WorkbenchPreferencePage() {ITPUB个人空间6N*bB)u'D*A
        super();ITPUB个人空间 Q8gt~P
    }

    public WorkbenchPreferencePage(String title) {ITPUB个人空间(V3lI;O"? U_,gQ+e
        super(title);
a|a-`{;d0    }

    public WorkbenchPreferencePage(String title, ImageDescriptor image) {
DU{,x!KZ(x7oB.Y0        super(title, image);ITPUB个人空间*ap/dfo
    }

    protected Control createContents(Composite parent) {
DJ1r7e'l/_0        Label label = new Label(parent, SWT.CENTER);
x+BE!Q4q0        label.setText("Greeting");ITPUB个人空间nKr`0N6AY
        _greeting = new Text(parent, SWT.SINGLE | SWT.BORDER);

        return parent;
RC#ln.C*AX6at&M0    }

    protected IPreferenceStore doGetPreferenceStore() {
,h,R.c(v&q\0        System.out.println("WorkbenchPreferencePage.doGetPreferenceStore()");ITPUB个人空间#m,g wB}
        return HelloWorldPlugin.getDefault().getPreferenceStore();
Yww3h)H&[|[0    }

    public void init(IWorkbench workbench) {
R#a(ru"MR%dan0   ITPUB个人空间&i%jZ/?z,uJ
    }

    protected void performDefaults() {
2gk5NI K5]0        System.out.println("WorkbenchPreferencePage.performDefaults()");ITPUB个人空间'I&G'}b"~ E],|3e
        IPreferenceStore prefStore = getPreferenceStore();
&R.z(D-Yr e_C0        prefStore.setValue(HelloWorldPlugin.GREETING, "world");ITPUB个人空间+pM%i5p.p`
        HelloWorldPlugin.getDefault().savePluginPreferences();

        _greeting.setText(prefStore.getString(HelloWorldPlugin.GREETING));ITPUB个人空间9R[Cp;l x
    }

    public boolean performOk() {ITPUB个人空间'B)a7g*WrL Vy I q
        boolean result = false;

        System.out.println("WorkbenchPreferencePage.performOk()");ITPUB个人空间c+e9K:nG2{a |
        IPreferenceStore prefStore = getPreferenceStore();
^p.aGA0        prefStore.setValue(HelloWorldPlugin.GREETING, _greeting.getText());
4q)`XS.U ?}0        HelloWorldPlugin.getDefault().savePluginPreferences();

        result = true;

        return result;ITPUB个人空间'd3jPJHKKg
    }ITPUB个人空间zWCBXr W
}

本例程只添加了一个Label控件和一个Text控件。若用户有兴趣可以添加自己完成的属性页,选择“window”→“preferences”菜单,打开首选项对话框,程序运行效果如图4所示。
3R3\p'uuH0 ITPUB个人空间 RO+a Bq9l

图4  首选项窗口

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

下载(com.free.proj.helloproject.rar)
Rr5R6W,@"~Q0jGKi0


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 :( :)

日历

« 2010-03-21  
 123456
78910111213
14151617181920
21222324252627
28293031   

数据统计

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

RSS订阅

Open Toolbar