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

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

实现项目特性插件

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

项目扩展点

用户已经了解了如何在Eclipse中添加视图、编辑器、透视图菜单和工具栏按钮。本节将要介绍如何加入自己的项目相关特性,其中包括向导、项目特性、构建器和属性页。项目特性扩展点如图1所示。
s;up%n7j:mRWM0 
;O#S2veR0

图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个人空间N#`^+}YF6UE%[St
扩展点在plugin.xml文件中的描述如下。

<extensionITPUB个人空间o}/pAN
      id="helloworldnature"
&e8iu{@1I)N0      point="org.eclipse.core.resources.natures">ITPUB个人空间0A p:o d4OCA"d!G'_z(g
   <runtime>
o u r;v@0      <run class="com.free.project.HelloWorldNature"/>ITPUB个人空间7u;['~+a;er
   </runtime>ITPUB个人空间L.yk$x-gP
</extension>

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

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

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

configure():当nature被添加到项目中时,通过configure方法配置当前项目。
9p5S0\9jh6~$A)CB0deconfigure():当nature从项目删除时,通过deconfigure方法删除相应配置。
$AH)F}WzSZc X$eO0nature对应的实现类为“HelloWorldNature”,在此实现类中主要功能是通过configure方法配置当前项目的构建器,代码如例程1所示。

例程1  HelloWorldNature.java
wI3E1I)Z:T0public class HelloWorldNature implements IProjectNature {

    private IProject _project;
*rz)rt q!_._0    //配置Nature
,m~$s2R0{+j0    public void configure() throws CoreException {
%?]J2c;T c;W0     System.out.println("configure");
A _#k|'HR"M ]C0        IProjectDescription projectDesc = _project.getDescription();ITPUB个人空间%x l)\&@U
        ICommand[] buildSpec = projectDesc.getBuildSpec();ITPUB个人空间T8mM/? ~8f*E,E,n6E[
        boolean hasBuilder = false;
/o6n H*XR"B q:|pSz1r3K0        //遍历项目的构建器
D:K)D q0|_m W7X"x2j:e0        for (int i = 0; i < buildSpec.length; ++i) {
d `^M+I{0                   if (buildSpec[i]
lU:}p~'a2W6l6Cg8y0                .getBuilderName()
:_ zxJe:?|O#^F0                .equals("com.free.proj.helloproject.helloworldbuilder")) {
\C;bq!}$S0                hasBuilder = true;ITPUB个人空间)PAAeS!X;d FoO
                System.out.println("true");ITPUB个人空间?+fy1DO/Z
                break;
6`,tE)pfo0            }ITPUB个人空间t s%S7z:n
        }

        if (hasBuilder == false) {ITPUB个人空间 V Aj S1R
         System.out.println("false");ITPUB个人空间.W1U+t;s-|
            ICommand newCommand = projectDesc.newCommand();
doB%b4`0            newCommand.setBuilderName("com.free.proj.helloproject.helloworldbuilder");ITPUB个人空间-Jdd U#p,A-E k
            ICommand[] buildSpecs = new ICommand[buildSpec.length + 1];

            System.arraycopy(buildSpec, 0, buildSpecs, 1, buildSpec.length);ITPUB个人空间J;RD.F[Tn*d^&R]
            buildSpecs[0] = newCommand;
U} R:Kv;W {'X|fKi0            projectDesc.setBuildSpec(buildSpecs);ITPUB个人空间or0?8hE:E#c
            _project.setDescription(projectDesc, null);ITPUB个人空间S E8t%@!f@5V%b`"rh#t
        }
,l!k;J C%a8Av0    }

    public void deconfigure() throws CoreException {ITPUB个人空间-VC6O)Iwv*YJ&d
      ITPUB个人空间"ESjn$Ee
    }
:|SWX?!d/|0    //获得Nature所关联的项目ITPUB个人空间&O h4]%[z/S}!W9v
    public IProject getProject() {ITPUB个人空间2Y%y;U!k#A"]w
     System.out.println("getProject");
6S&a!J'p h4u4I0               return _project;
/z/Z4h,fz,Qam(W0    }
8O;d,\Nc5Wh0   //设置Nature所关联的项目
n,o9WT U{t0    public void setProject(IProject project) {ITPUB个人空间 q C{ B |/a\.r&W
      System.out.println("setProject");ITPUB个人空间v-A bX \C'hy5u'i
      _project = project;ITPUB个人空间%Wv`V f3K f
    }

}

提示:此外构建器的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个人空间+Y,|s1W8P!x]
扩展点在plugin.xml文件中的描述如下。

<extension
5Z!x+p7z)E K0         id="helloworldbuilder" name="hello world, bulder"
s)WTzoTVj0         point="org.eclipse.core.resources.builders">ITPUB个人空间X,jB s?)H h
      <builder>ITPUB个人空间:I7{)u{aC}P
         <run class="com.free.project.HelloWorldBuilder"/>ITPUB个人空间|&P2U`"P.v-a"R7ST
      </builder>ITPUB个人空间V5a;YY+jGE-[k
   </extension>

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

例程2  HelloWorldBuilder.java
s5n2BM7RY ^1d0public class HelloWorldBuilder extends IncrementalProjectBuilder {
C)rX N3S:i/ws0    //实现资源监听器ITPUB个人空间%E w/i)?&V9v M
    private class HelloWorldVisitor implements IResourceVisitor {ITPUB个人空间2FyMH'nK
        public boolean visit(IResource resource) throws CoreException {
\-jH9t+Bv8bDF0            System.out.println("**** HelloWorldVisitor.visit() ****");ITPUB个人空间GZF)c Kp@]F;[ Q#t
            switch (resource.getType()) {ITPUB个人空间-uy]z]:GIMX]
            case IResource.PROJECT:ITPUB个人空间Q\Y9h:h
                System.out.println("Project added: " + resource.getName());
uz ^%sXu(^.w0                break;ITPUB个人空间9G/e5oQ&YFWZ
            case IResource.FOLDER:
C*G0Aw-D1YE0                System.out.println("Folder added: " + resource.getName());
1d;w/RYQ e U}g)o V0                break;
*iR3n,ETH5g0            case IResource.FILE:
!S3Ke)r(r0Bi%^0                System.out.println("File added: " + resource.getName());
2z']"E@%]S:bs hed0                break;ITPUB个人空间#Fd$E%e1Be x W
            }

            return true;ITPUB个人空间KaCM`OKr\#Rv7Z
        }
,` Z6{TsR,?.o8K0    }ITPUB个人空间!eO^8u%E n*z
    //实现资源监听器
u:Ux(i{:KQ)j0    private class HelloWorldDeltaVisitor implements IResourceDeltaVisitor {
V~wT:I"lm h0        public boolean visit(IResourceDelta delta) throws CoreException {
D(m"JOz#? Wa#M0            System.out.println("**** HelloWorldDeltaVisitor.visit() ****");
0oU#w7^xj5K$I0            String type = null;ITPUB个人空间5K/ORs,]0?Gw#U
            switch (delta.getResource().getType()) {ITPUB个人空间0n{EHx1Qa[#h
            case IResource.ROOT:ITPUB个人空间|Aq[8J}y8h/Z
                type = "ROOT";ITPUB个人空间p1]F2K1o/OzHz
                break;
Ww,cfV0            case IResource.PROJECT:ITPUB个人空间u3h7i~ i;U
                type = "Project";ITPUB个人空间7O4s3?3z4`(w$TI^T
                break;
:f4bWRb,]0            case IResource.FOLDER:
[QTTQ}!~y0                type = "Folder";
9tROq1gS O3{0                break;ITPUB个人空间[c!F)gLG4Y
            case IResource.FILE:ITPUB个人空间q7h7|;M1~ s4q;[ l:p0g
                type = "File";ITPUB个人空间 ]]#cy] _P3w(P/D
                break;
}7sa-T/o9G7VJ0            }

            switch (delta.getKind()) {ITPUB个人空间](T.k-NiS&uYR
            case IResourceDelta.ADDED:ITPUB个人空间9R.V3rI9[2}_z*l3{
                System.out.println(type + " added: "+ delta.getResource().getName());
7`&bSp-i0                break;ITPUB个人空间6J7R^y La-o%bn
            case IResourceDelta.CHANGED:
-]h*JI.A0OK0                System.out.println(type + " changed: "
fAD9b f f'j5c s0                        + delta.getResource().getName());ITPUB个人空间#U z'hUMU/c*c
                break;
M2w'A0V U uA0            case IResourceDelta.REMOVED:ITPUB个人空间 p6tl4nF|%D`jq
                System.out.println(type + " removed: "
Q0U YEbj0                        + delta.getResource().getName());ITPUB个人空间x[I1m}K|#x
                break;
7CKE%Mh&Dj|0            }

            return true;
,J){VhD2I(t0        }
%~)j V6z&n Ls1O0    }

    public HelloWorldBuilder() {ITPUB个人空间}*EI5{S.d3V+eZs v
        System.out.println("HelloWorldBuilder.constructor()");
k3`,X3h4hH$o0    }ITPUB个人空间c {iT7q.t;qNH!I
    //开始构建
6Eb2q6Xo:kw_W0    protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
.k [.I3Ou.E)J0            throws CoreException {ITPUB个人空间-C H)^,p ]Zr_yU%]
        System.out.println("HelloWorldBuilder.build()");
gciP6m M)S0        //当构建类型不同时,添加不同的资源监听器
)E7tY1g5m0        if (kind == IncrementalProjectBuilder.FULL_BUILD) {
h sFyz$l}0            System.out.println("FULL_BUILD");
u6qcf2[7T8Jg0p0            getProject().accept(new HelloWorldVisitor());ITPUB个人空间7l,u.l-yW U
        } else {
\+j/|:l1pJn0            IResourceDelta delta = getDelta(getProject());
g+t"p+l3m:P0            if (delta == null) {ITPUB个人空间 RV0r&E8Ey"TA3x
                System.out.println("AUTO_BUILD");ITPUB个人空间{7t;DO f
                getProject().accept(new HelloWorldVisitor());ITPUB个人空间[`UM Q'IR
            } else {
3H.wB"}:w!T\ XOI0                System.out.println("INCREMENTAL_BUILD");ITPUB个人空间v3fe2Y/_"I| |
                delta.accept(new HelloWorldDeltaVisitor());
1F,dzD&K2wW0            }
6t!a9s6B1|9nN$g0        }
;UYOPq&W(~a0        return null;ITPUB个人空间%w(i%Q`"sQ
    }

}ITPUB个人空间+qj,T[$Gz @2z#G%G
在用户建立的项目中,如果资源发生改变,builder会调用“HelloWorldDeltaVisitor”类进行增量构建处理,当清除项目时会调用“HelloWorldVisitor”类进行完全构建处理。插件运行后,当用户选择自定义项目时,用户可以打开项目属性窗口看到“hello world, builder”构建器,如图2所示。
Zo,q/G#qTa0 ITPUB个人空间 N8D2R*zL#E"y

图2  项目属性窗口

工程向导扩展点及实现类

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

1.  在插件清单文件的Extensions页中添加“org.eclipse.ui.newWizards”扩展点。
)?`;C7RPo2q2F02.  在“org.eclipse.ui.newWizards”节点下添加category子节点,设置ID属性为“com.free.project.wizard.category”,name属性为“HelloWorld Project Category”。
R b;B`5NS!JF3z03.  在“org.eclipse.ui.newWizards”节点下添加wizard节点,设置实现类class为“com.free.project.HelloWorldWizard”,ID属性为“com.free.project.wizard”。

扩展点在plugin.xml文件中的描述如下:ITPUB个人空间)tqr,?&`
<extension
;k7QT7h?"{l&|O0         point="org.eclipse.ui.newWizards">
L N T3ze3H x4E0      <category
9I"C`9_C8h2a;@0            name="HelloWorld  Project Category"
.l$R/o8X8f7pf }9e0            id="com.free.project.wizard.category"/>
R c3`'i3{6l*F7n!f0      <wizard
I/i"Y9h G$gC0            class="com.free.project.HelloWorldWizard"ITPUB个人空间/g X}.H Bfr4B&Y
            category="com.free.project.wizard.category"
'O `gSD0            name="HelloWorld Project Wizard"ITPUB个人空间6U%O-CC_EEdo
            id="com.free.project.wizard"/>ITPUB个人空间6l KCwy
</extension>

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

例程3  HelloWorldWizard.javaITPUB个人空间p \RP?-NK xu4P8t9M
public class HelloWorldWizard extends Wizard implements INewWizard {

    private WizardNewProjectCreationPage _page;

    public HelloWorldWizard() {ITPUB个人空间U8{!_nIh-U,o*T
        super();ITPUB个人空间([I%[9T_O0U(r U7{/_
    }ITPUB个人空间:h{8h-|g/o2J1e i
    //添加向导页
8u"N'N DD*Z'n?0    public void addPages() {
^2t"N%tMv e8Ca\0        _page = new WizardNewProjectCreationPage("page1");
]&K&J7v6C0        _page.setDescription("Page 1 of Helloworld New Wizard");ITPUB个人空间%i9Z!GZ9w4nt~ G
        _page.setTitle("HelloWorld Wizard");ITPUB个人空间Nf M+tR0~nb(J
        addPage(_page);
@2u-\c*} ~ X q0    }
;AvuH@aQ#^M0    //完成向导
!z~&v&QU:V0    public boolean performFinish() {
%T7JxBq{0        boolean result = false;

        System.out.println("project page.name = " + _page.getProjectName());ITPUB个人空间 AE5Q)Q4VJ
        System.out.println("project page.path = " + _page.getLocationPath());
:pN(d6o3_0        IProject project = _page.getProjectHandle();
;VM0j'{.c|4zz2_0        try {
!Zp"i|pNB$g0            project.create(null);ITPUB个人空间RGQ2C#cm;R~!_|
            result = true;
2Q$TKX~N0        } catch (CoreException e) {
'z4A nprf{2JC1m0            e.printStackTrace();
[%sa;KQ_@m_0        }

        IProjectDescription projectDesc = null;
c2r/HB0{*^4O+l0        try {ITPUB个人空间1r%\}D AEX
            project.open(null);
@y;` p;w,f)l0            projectDesc = project.getDescription();ITPUB个人空间bd Dx ?6D"x
        } catch (CoreException e1) {
n}:Yk-j1c T`0            e1.printStackTrace();ITPUB个人空间H|L:J!o#`
        }

        String[] natureIds = projectDesc.getNatureIds();ITPUB个人空间(I7BY7E3I#NEuWT*H
        String[] newNatureIds = new String[natureIds.length + 1];
n4Af3| ovynb0        System.arraycopy(natureIds, 0, newNatureIds, 0, natureIds.length);
[ B.Uz5D0        newNatureIds[natureIds.length] = "com.free.proj.helloproject.helloworldnature";ITPUB个人空间 k{{8q}j.n }
        projectDesc.setNatureIds(newNatureIds);ITPUB个人空间TMOk7S5mc
        try {
$U!H;D6HS q s2^?PD0            project.setDescription(projectDesc, null);ITPUB个人空间#BCBM-F_KC
        } catch (CoreException e2) {ITPUB个人空间mZ s!?t z:B w LN'C
            e2.printStackTrace();ITPUB个人空间8g(e(fvF'g~
        }

        return result;
;z1j!W~&V1a)NB0    }

    public void init(IWorkbench workbench, IStructuredSelection selection) {
Im h'RvO*|0      
"VZD ng:m,T0    }

}

本例程中没有实现用户定义的向导页,而是用Eclipse下的“WizardNewProjectCreationPage”页来作为向导页。用户也可以定义向导页,如果有兴趣可以参考多页签编辑器中的例子源代码,多页签编辑器插件已经实现了向导。本例中可以通过新建菜单新建用户定义的项目,向导对话框如图3所示。
s7o-Q[Q(`3?0 
p d*u:J8n3D)_9zzJ0

图3  向导对话框

首选项页扩展点及实现类

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

1.  在插件清单文件的Extensions页中添加“org.eclipse.ui.preferencePages”扩展点。
W5X0Q%P|,uC02.  在“org.eclipse.ui.preferencePages”节点下添加page子节点,设置节点的ID属性为“com.free.project.page”,name属性为“HelloWorld”,class属性为“com.free.project.Workbench- PreferencePage”。
(wV'V,e4Y8x!_v%N5ZM0扩展点在plugin.xml文件中的描述如下。

<extensionITPUB个人空间3o+e[q)zLI;s
    point="org.eclipse.ui.preferencePages">
*n ]L*~:Bn0 <pageITPUB个人空间'j$^]8U3X
       class="com.free.project.WorkbenchPreferencePage"
FGU6UH;V;}0       name="HelloWorld"
7LP+H~ f:D0@ja0       id="com.free.project.page"/>ITPUB个人空间aW_ ~,oV v1T,n
</extension>

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

例程4  WorkbenchPreferencePage.java
$B5YoTSw q8`0public class WorkbenchPreferencePage extends PreferencePage implements
lv8WV X0        IWorkbenchPreferencePage {

    private Text _greeting;

    public WorkbenchPreferencePage() {
Yg.DK\ V8dRp4@0        super();ITPUB个人空间?W9dj%Ji l1[
    }

    public WorkbenchPreferencePage(String title) {ITPUB个人空间 tGKq'@s
        super(title);
^P,P6g!B^ ?!iO0    }

    public WorkbenchPreferencePage(String title, ImageDescriptor image) {ITPUB个人空间}#BF'I:B3Z1W
        super(title, image);ITPUB个人空间 \ I:n5|7KD7@
    }

    protected Control createContents(Composite parent) {ITPUB个人空间 ^&I,K;?8d4f7rZ
        Label label = new Label(parent, SWT.CENTER);
9TP e$k%yOc2D9^!?0        label.setText("Greeting");ITPUB个人空间%U/_rIB7~a
        _greeting = new Text(parent, SWT.SINGLE | SWT.BORDER);

        return parent;
-l-ZH1[ X*E0    }

    protected IPreferenceStore doGetPreferenceStore() {
i?,bP;Bqob0        System.out.println("WorkbenchPreferencePage.doGetPreferenceStore()");ITPUB个人空间%T ^#rx_ O T)[T7R
        return HelloWorldPlugin.getDefault().getPreferenceStore();ITPUB个人空间Y7M\UK HUmel
    }

    public void init(IWorkbench workbench) {
O@%y LEiP0   ITPUB个人空间&\G(kX,h(u
    }

    protected void performDefaults() {ITPUB个人空间.iZ`#`#[w1m
        System.out.println("WorkbenchPreferencePage.performDefaults()");
5\l j6p3w z3k0        IPreferenceStore prefStore = getPreferenceStore();ITPUB个人空间_%T2w OY[A1J\j
        prefStore.setValue(HelloWorldPlugin.GREETING, "world");ITPUB个人空间bZ&x1^&z f
        HelloWorldPlugin.getDefault().savePluginPreferences();

        _greeting.setText(prefStore.getString(HelloWorldPlugin.GREETING));ITPUB个人空间+q9uk5} }2}
    }

    public boolean performOk() {ITPUB个人空间0w2l K9i!D$['x
        boolean result = false;

        System.out.println("WorkbenchPreferencePage.performOk()");ITPUB个人空间IF%m Tx}Wn
        IPreferenceStore prefStore = getPreferenceStore();ITPUB个人空间3LMQ k8DI
        prefStore.setValue(HelloWorldPlugin.GREETING, _greeting.getText());ITPUB个人空间||?EZ[
        HelloWorldPlugin.getDefault().savePluginPreferences();

        result = true;

        return result;
+By)o'^,s8e:q0    }ITPUB个人空间&C%Z _/e)j
}

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

图4  首选项窗口

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

下载(com.free.proj.helloproject.rar)ITPUB个人空间A5W N g?p


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

日历

« 2012-02-10  
   1234
567891011
12131415161718
19202122232425
26272829   

数据统计

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

RSS订阅

Open Toolbar