NetBeans IDE 6.1 插件开发示例

转载请保留作者信息:

作者:88250

Bloghttp:/blog.csdn.net/DL88250

MSN & Gmail & QQ[email protected]

NetBeans IDE 是基于NetBeans Platform搭建的,它的所有功能都是以插件的方式实现的。我们也可以基于NetBeans Platform实现自己的应用,这一点,与Eclipse RCP是等同的。首先,我们先来熟悉一下NetBeans Module的开发 :-)。这个例子是一个用于配置NetBeans启动参数的插件,用它可以使用图形界面配置NetBeans启动参数。当然了,这这是一个例子,Bugs比较多,要使用同种功能的插件,看这里

准备

点此访问NetBeans下载站点。下载最新的Java基本开发套件就可以了。

开始

1. 创建工程

新建工程,选择模块开发:
NetBeans IDE 6.1 插件开发示例

工程命名为CustomStartup,其他的使用默认配置。

2. 编写测试用例

插件随小,无脏俱全哦~ 再说,本着TDD的原则,我们还是先编写一下测试用例吧。
NetBeans IDE 6.1 插件开发示例

测试代码如下:


/*
*@(#)NBConfFileJUnitTest.java
*Author:88250<[email protected]>,
http://blog.csdn.net/DL88250
*CreatedonMay17,2008,11:19:21AM
*
*Thisprogramisfreesoftware;youcanredistributeitand/ormodify
*itunderthetermsoftheGNUGeneralPublicLicenseaspublishedby
*theFreeSoftwareFoundation;eitherversion3oftheLicense,or
*(atyouroption)anylaterversion.
*
*Thisprogramisdistributedinthehopethatitwillbeuseful,
*butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof
*MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe
*GNULibraryGeneralPublicLicenseformoredetails.
*
*YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense
*alongwiththisprogram;ifnot,writetotheFreeSoftware
*Foundation,Inc.,59TemplePlace-Suite330,Boston,MA02111-1307,USA.
*/
packagecn.edu.ynu.sei.customstartup.test;

importjava.io.BufferedReader;
importjava.io.File;
importjava.io.FileReader;
importjava.io.IOException;
importjava.util.Enumeration;
importjava.util.List;
importjava.util.Properties;
importorg.junit.After;
importorg.junit.AfterClass;
importorg.junit.Before;
importorg.junit.BeforeClass;
importorg.junit.Test;
importorg.openide.util.Exceptions;
importstaticorg.junit.Assert.*;

/**
*NBConfFileTestCase.
*
@author88250<[email protected]>,http://blog.csdn.net/DL88250
*
@version1.0.0.0,May17,2008
*/
publicclassNBConfFileJUnitTest{

privatestaticcn.edu.ynu.sei.customstartup.NBConfFileinstance;

publicNBConfFileJUnitTest(){
instance
=newcn.edu.ynu.sei.customstartup.NBConfFile();

}

@BeforeClass
publicstaticvoidsetUpClass()throwsException{
//simulatetheNetBeanslunchertosetsystemproperty
System.setProperty("netbeans.home",
"/home/daniel/Work/netbeans-6.1/platform8");
}

@AfterClass
publicstaticvoidtearDownClass()throwsException{
}

@Before
publicvoidsetUp(){
}

@After
publicvoidtearDown(){
}

@Test
publicvoidgetLocation(){
System.out.println(
"getLocation");
assertEquals(
"/home/daniel/Work/netbeans-6.1/etc/netbeans.conf",
instance.getLocation());
}

@Test
publicvoidgetFile(){
System.out.println(
"getFile");
Filenetbeans_conf
=instance.getFile();
assertTrue(netbeans_conf.exists());
assertEquals(
"netbeans.conf",netbeans_conf.getName());
BufferedReaderreader;
//Stringexpect=
//"#${HOME}willbereplacedbyJVMuser.homesystemproperty";
Stringexpect="###propertieswrittenbyCustomStartupmodule";
Stringactual
=null;
try{
reader
=newBufferedReader(newFileReader(netbeans_conf));
actual
=reader.readLine();
}
catch(IOExceptionex){
Exceptions.printStackTrace(ex);
}
assertEquals(expect,actual);
}

@Test
publicvoidbackupConfFile(){
System.out.println(
"backupConfFile");
instance.backupConfFile();
assertTrue(instance.getBackupFile().exists());
}

@Test
publicvoidgetBackupFile(){
System.out.println(
"getBackupFile");
Fileactual
=instance.getBackupFile();
assertEquals(
"netbeans.conf.backup",actual.getName());
}

@Test
publicvoidgetParameters(){
System.out.println(
"getParameters");
Propertiesparas
=instance.getParameters();
Enumeration
<?>keys=paras.propertyNames();
while(keys.hasMoreElements()){
Stringkey
=keys.nextElement().toString();
Stringvalue
=paras.getProperty(key);
System.out.println(key
+"="+value);
}

assertEquals(
""${HOME}/.netbeans/6.1"",
paras.getProperty(
"netbeans_default_userdir"));
}

@Test
publicvoidgetNetBeansDefaultOptions(){
System.out.println(
"getNetBeansDefaultOptions");
List
<String>options=instance.getNetBeansDefaultOptions();
for(Stringoption:options){
System.out.println(option);
}

assertEquals(
"-J-client",options.get(0));
assertEquals(
"--fontsize10",options.get(options.size()-1));
}

@Test
publicvoidgetNetBeansJDKHome(){
System.out.println(
"getNetBeansJDKHome");
Stringexpect
="/usr/lib/jvm/java-6-sun/";
Stringactual
=instance.getNetBeansJDKHome();
assertEquals(expect,actual);
}

@Test
publicvoidsetNetBeansJDKHome(){
System.out.println(
"setNetBeansJDKHome");
StringjdkHome
="/usr/lib/jvm/java-6-sun/";
instance.setNetBeansJDKHome(jdkHome);

assertEquals(jdkHome,instance.getNetBeansJDKHome());
}

@Test
publicvoidaddNetBeansDefaultOptions(){
System.out.println(
"addNetBeansDefaultOptions");
Stringpara
="--fontsize15";
instance.addNetBeansDefaultOptions(para);
assertEquals(para,instance.getNetBeansDefaultOptions().get(instance.
getNetBeansDefaultOptions().
size()
-1));
}

@Test
publicvoidremoveNetBeansDefaultOptions(){
System.out.println(
"removeNetBeansDefaultOptions");
instance.removeNetBeansDefaultOptions(
0);
assertEquals(
"-J-Xss16m",instance.getNetBeansDefaultOptions().get(0));
}

@Test
publicvoideditNetBeansDefaultOptions(){
System.out.println(
"editNetBeansDefaultOptions");
instance.editNetBeansDefaultOptions(
0,"--test10");
assertEquals(
"--test10",instance.getNetBeansDefaultOptions().get(0));
}
}

3. 编写逻辑实现代码

/*
*@(#)NBConfFile.java
*Author:88250<[email protected]>,
http://blog.csdn.net/DL88250
*CreatedonMay17,2008,11:23:53AM
*
*Thisprogramisfreesoftware;youcanredistributeitand/ormodify
*itunderthetermsoftheGNUGeneralPublicLicenseaspublishedby
*theFreeSoftwareFoundation;eitherversion3oftheLicense,or
*(atyouroption)anylaterversion.
*
*Thisprogramisdistributedinthehopethatitwillbeuseful,
*butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof
*MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe
*GNULibraryGeneralPublicLicenseformoredetails.
*
*YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense
*alongwiththisprogram;ifnot,writetotheFreeSoftware
*Foundation,Inc.,59TemplePlace-Suite330,Boston,MA02111-1307,USA.
*/
packagecn.edu.ynu.sei.customstartup;

importjava.io.BufferedReader;
importjava.io.BufferedWriter;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.FileOutputStream;
importjava.io.FileReader;
importjava.io.FileWriter;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.OutputStream;
importjava.util.ArrayList;
importjava.util.Enumeration;
importjava.util.List;
importjava.util.Properties;
importorg.openide.util.Exceptions;

/**
*NetBeansstartupconfigurationfiledescription.
*
@author88250<[email protected]>,http://blog.csdn.net/DL88250
*
@version1.0.0.0,May17,2008
*/
publicclassNBConfFile{

/**
*configurationfilelocation(fullpath,fullname)
*/
privateStringlocation;
/**
*configurationfile
*/
privateFileself;

/**
*Defaultconstructor.
*/
publicNBConfFile(){
initLocation();
}

/**
*AddanewNetBeansstartupparameter.
*
@paramparathenewparametertobeadded
*/
publicvoidaddNetBeansDefaultOptions(Stringpara){
List
<String>options=getNetBeansDefaultOptions();
options.add(para);
persistNBOptions(options);
}

/**
*EditaNetBeansstartupparameter.
*
@paramindexparameterindex
*
@paramnewValuethenewparametervalue
*/
publicvoideditNetBeansDefaultOptions(intindex,StringnewValue){
List
<String>options=getNetBeansDefaultOptions();
if(index>=options.size()){
return;
}
options.set(index,newValue);
persistNBOptions(options);
}

/**
*RemoveaNetBeansstartupparameter.
*
@paramindexaparametertobedeleted
*/
publicvoidremoveNetBeansDefaultOptions(intindex){
List
<String>options=getNetBeansDefaultOptions();
if(index>=options.size()){
return;
}
options.remove(index);
persistNBOptions(options);
}

/**
*Backupconfigurationfile.Thebackupnamed"netbeans.conf.backup",and
*inthesamepathwithoriginal.
*/
publicvoidbackupConfFile(){
InputStreaminFile
=null;
OutputStreamoutFile
=null;
try{
inFile
=newFileInputStream(location);
outFile
=newFileOutputStream(location+".backup");
org.openide.filesystems.FileUtil.copy(inFile,outFile);
}
catch(IOExceptionex){
Exceptions.printStackTrace(ex);
}
finally{
try{
inFile.close();
outFile.close();
}
catch(IOExceptionex){
Exceptions.printStackTrace(ex);
}
}
}

/**
*Gettheconfigurationbackupfile.
*
@returnafilenamed"netbeans.conf.backup"
*/
publicFilegetBackupFile(){
Fileret
=newFile(location+".backup");
if(ret.exists()){
returnret;
}
else{
thrownewRuntimeException("netbeans.conf.backupinexists!");
}
}

/**
*Gettheconfigurationfile.
*
@return{@link#self}
*/
publicFilegetFile(){
self
=newFile(location);
if(self.exists()){
returnself;
}
else{
thrownewRuntimeException("netbeans.confinexists!");
}
}

/**
*Gettheconfigurationfilelocation.
*
@return{@link#location}
*/
publicStringgetLocation(){
returnlocation;
}

/**
*Getallvaluesdescribedin"netbeans_default_options",file"netbeans.conf".
*
@returnifnetbeans_default_options="-J-client-J-Xss16m-J-Xms128m-J-XX:PermSize=256m<b>--fontsize10</b>...",
*returnalistlikethis:{"-J-client","-J-Xss16m","-J-Xms128m","-J-XX:PermSize=256m",<b>"--fontsize10"</b>...}
*/
publicList<String>getNetBeansDefaultOptions(){
String[]allOptions
=getParameters().getProperty(
"netbeans_default_options").split("/s");
intlast=allOptions.length-1;
//removethefirstdoublequotation
allOptions[0]=allOptions[0].substring(1,allOptions[0].length());
//removethelastdoublequotation
allOptions[last]=
allOptions[last].substring(
0,
allOptions[last].length()
-1);
List
<String>ret=newArrayList<String>();

for(inti=0;i<allOptions.length;i++){
Stringitem
=allOptions[i];
//confirmthestartupparameter'sbeginning
if(item.length()>=2){
Stringbeginning
=item.substring(0,2);

if(beginning.equals("-J")){
//JVMParameters
ret.add(item);
}
elseif(beginning.equals("--")){
//IDEParameters
if(item.startsWith("--laf")){
//--lafui_class_name:UseagivenclassastheIDE'slookandfeel.
ret.add(item+""+allOptions[i+1]);
}
elseif(item.startsWith("--fontsize")){
//--fontsizesize:UseagivensizeinpointsasthebasicfontsizefortheIDEuserinterface.
ret.add(item+""+allOptions[i+1]);
}
}
else{
//TODOother'sconditions
}
}
}

returnret;
}

/**
*GetJDKHOMEbyNetBeansusing.
*
@returntheJDKHOMEpath,suchas"/usr/lib/jvm/java-6-sun/"
*/
publicStringgetNetBeansJDKHome(){
Stringret
=getParameters().getProperty("netbeans_jdkhome");
//removethedoublequotation
ret=ret.substring(1,ret.length()-1);

returnret;
}

/**
*Getallstartupparametersinfile"netbeans.conf".Everyparameterlikethis:
*<p>
*-J-Xss16m
*-J-XX:PermSize=256m
*-J-Xverify:none
*--lafjavax.swing.plaf.metal.MetalLookAndFeel
*--fontsize10
*</p>
*
@return
*/
publicPropertiesgetParameters(){
Propertiesparas
=newProperties();
BufferedReadernb_confReader
=null;
try{
nb_confReader
=newBufferedReader(newFileReader(getFile()));

StringaLine
=null;
while((aLine=nb_confReader.readLine())!=null){
if(aLine==null||aLine.equals("")||aLine.charAt(0)=='#'){
continue;
}
Stringkey
=aLine.substring(0,aLine.indexOf('='));
Stringvalue
=aLine.substring(aLine.indexOf('=')+1,
aLine.length());
paras.setProperty(key,value);
}
}
catch(IOExceptionex){
Exceptions.printStackTrace(ex);
thrownewRuntimeException("netbeans.confreaderror!!");
}

returnparas;
}

/**
*SetNetBEansJDKHomepath.
*<p>
*NOTE:thespecifiedjdkHomepathisfullpathwithoudoublequotation.
*,suchas<center>/usr/lib/jvm/java-6-sun/</center>
*</p>
*
@paramjdkHomeJDKHomepath
*/
publicvoidsetNetBeansJDKHome(StringjdkHome){
Propertiesparas
=getParameters();
paras.setProperty(
"netbeans_jdkhome","""+jdkHome+""");
setParameters(paras);
}

/**
*PersistNetBeansOptions.
*
@paramoptionsoptionslist
*/
privatevoidpersistNBOptions(List<String>options){

Propertiesparas
=getParameters();
StringoptionsStr
="";
for(Stringoption:options){
optionsStr
+=option+"";
}
optionsStr
=optionsStr.trim();

paras.setProperty(
"netbeans_default_options","""+optionsStr+""");
setParameters(paras);
}

/**
*Setallstartupparametersinfile"netbeans.conf".
*
@paramparastheparametersstorebya<code>Properties<code>
*/
privatevoidsetParameters(Propertiesparas){
BufferedWriterwriter;
try{
writer
=newBufferedWriter(newFileWriter(location));
writer.write(
"###propertieswrittenbyCustomStartupmodule");
writer.newLine();
Enumeration
<?>keys=paras.propertyNames();
while(keys.hasMoreElements()){
Stringkey
=keys.nextElement().toString();
Stringvalue
=paras.getProperty(key);
writer.write(key
+"="+value);
writer.newLine();
}
writer.close();
}
catch(IOExceptionex){
Exceptions.printStackTrace(ex);
}
}

/**
*Initializenetbeans.conf'slocation.
*/
privatevoidinitLocation(){
location
=System.getProperty("netbeans.home");

//remove"/platform8"
location=location.substring(0,location.lastIndexOf(File.separator));
//add"/etc/netbeans.conf"
location+=File.separator+"etc"+File.separator+"netbeans.conf";
//TODOOSsettings
//System.out.println(org.openide.util.Utilities.isUnix());
//System.out.println(org.openide.util.Utilities.isWindows());
}
}

4. 开始插件咯~

好了,上面贴了很多代码,貌似和NetBeans的插件开发没什么联系。现在我们正式开始介绍插件开发(模块开发)!

a. 添加需要的依赖库,也就是Platform的一些APIs:

NetBeans IDE 6.1 插件开发示例

b.建立Options Panel类型的文件:

NetBeans IDE 6.1 插件开发示例

c. 打开Panel,设计界面:

NetBeans IDE 6.1 插件开发示例

d. 主要事件处理代码:


privatevoidconfirmJDKHomeBtnActionPerformed(java.awt.event.ActionEventevt){
StringjdkHomeInput
=jdkHomeTextField.getText();

nBConfFile.setNetBeansJDKHome(jdkHomeInput);
}

privatevoidaddParasBtnActionPerformed(java.awt.event.ActionEventevt){
StringnewValue
=(String)this.argumentsTbl.getCellEditor(
this.argumentsTbl.getEditingRow(),0).getCellEditorValue();
Vector
<String>newRow=newVector<String>();
newRow.add(newValue);
this.argsTblModel.addRow(newRow);

}

privatevoidremoveParasBtnActionPerformed(java.awt.event.ActionEventevt){
intselectedRow=this.argumentsTbl.getSelectedRow();
this.argsTblModel.removeRow(selectedRow);
nBConfFile.removeNetBeansDefaultOptions(selectedRow);
}

privatevoidargumentsTblPropertyChange(java.beans.PropertyChangeEventevt){
intselectedRow=this.argumentsTbl.getSelectedRow();
if(selectedRow>=0&&selectedRow<=nBConfFile.getNetBeansDefaultOptions().
size()){
//editparameter
StringnewValue=this.argsTblModel.getValueAt(selectedRow,
0).toString();
nBConfFile.editNetBeansDefaultOptions(selectedRow,newValue);
}
elseif(selectedRow>=0&&this.argsTblModel!=null&&
this.argsTblModel.getValueAt(selectedRow,0)!=null){
//addparameter
StringnewValue=this.argsTblModel.getValueAt(selectedRow,
0).toString();
nBConfFile.addNetBeansDefaultOptions(newValue);
}
}

5. 测试

直接运行工程就可以了:
NetBeans IDE 6.1 插件开发示例

总结

较NetBeans与eclipse的插件开发比较,我觉得NB的要方便一些。特别是NB Platform提供的APIs比较“人性化”。而且NB在开发时要稳定一点。不过,随着JDK7里正式内置了OSGi,情况可能会有所改变。让我们拭目以待!