Hacking NetBeans #4 - Create Your Own Options



One of the things you'll probably want to do if you're writing your plug-in is to have your own options. NetBeans can take care of their lifecycle - they are loaded on IDE startup and if changed they are saved to the userdir. You have probably noticed the small dialog which appears when you close IDE, saving options of all modules is one of the actions performed. So the IDE takes care about management of your options - you don't have to write quite a lot of code which is already a part of NetBeans.

How to add your options? As usual, you'll have to start with the layer.xml file:

    <folder name="Services">
    	<file name="org-netbeans-modules-mymodule-MyModuleSettings.settings" url="MyModuleSettings.xml" />
    </folder>

This way you add to the folder Services a settings file, which is the MyModuleSettings.xml file in the same directory as your layer.xml. The MyModuleSettings.xml specifies the class which will be used for options of your module:

<?xml version="1.0"?>
<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
<settings version="1.0">
    <module name="org.netbeans.modules.mymodule"/>
    <instanceof class="org.openide.util.SharedClassObject"/>
    <instanceof class="org.openide.options.SystemOption"/>
    <instanceof class="org.netbeans.modules.mymodule.MyModuleSettings"/>
    <instance class="org.netbeans.modules.mymodule.MyModuleSettings"/>
</settings>

The MyModuleSettings.xml files specifies the class which will be instanciated when your options are needed. This class extends the SystemOption class. As specified in xml file, it is located in org/netbeans/modules/mymodule/MyModuleSettings.java. The class has a special format:

public class MyModuleSettings extends SystemOption {
    // unique serial number for serialization
    static final long serialVersionUID = 34343534534534573L;    

    // the names of options you'll use
    public static final String PROP_HOSTNAME = "hostname";
    public static final String PROP_PORT = "port";

    // initialization method
    protected void initialize () {        
        // calles SystemOption's initialize
        super.initialize();
        
        // default values
        putProperty(PROP_HOSTNAME, "localhost", true);
        putProperty(PROP_PORT, "4976", true);
    }

    // this method serializes the options 
    public void writeExternal (ObjectOutput out) throws IOException {
        out.writeObject(getProperty(PROP_HOSTNAME));
        out.writeObject(getProperty(PROP_PORT));
    }

    // this method deserializes the options
    private void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        putProperty(PROP_HOSTNAME, in.readObject(), true);
        putProperty(PROP_PORT, in.readObject(), true);
    }

    // readable name of options
    public String displayName() {
        return "My Module's Options";
    }

    // help context
    public HelpCtx getHelpCtx () {
        return new HelpCtx(MyModuleSettings.class); 
    }
    
    // set Hostname Option
    public void setHostname(String hostname) {
        putProperty(PROP_HOSTNAME, hostname, true);
    }

    // get Hostname Option
    public String getHostname() {
        return (String) getProperty(PROP_HOSTNAME);
    }         

    // set Port Option
    public void setPort(Integer port) {
        putProperty(PROP_PORT, host, true);
    }

    // get Port Option
    public Integer getPort() {
        return (Integer) getProperty(PROP_PORT);
    }         
}

This is basicly all you need to make the options work - whatever you write using setXXX method will be saved to the userdir (all options need to be serializable objects). Your module can read the options by calling the getXXX methods and they're loaded. You can create this way as many options as you want (but keep in mind it's better to keep the number of options small - we know what we are talking about). As you know, things get always complex, one of the first things you'll need to support various versions. But that's mostly solved by just writing to the first position an Integer with version and add a switch to decide what to do according to this version.

So this code handles reading and writing of options, but you'll probably also want them to be displayed. To do that, you need at first to create a beaninfo class, which will add additional information to your options. The name of the beaninfo class is always name of your class + BeanInfo.

public class MyModuleSettingsBeanInfo extends SimpleBeanInfo {
    
    public PropertyDescriptor[] getPropertyDescriptors() {
        try {
            PropertyDescriptor hostname =
                    new PropertyDescriptor("hostname", MyModuleSettings.class);
            hostname.setDisplayName("Hostname");
            hostname.setShortDescription("This option sets the hostname.");
            PropertyDescriptor port =
                    new PropertyDescriptor("port", MyModuleSettings.class);
            port.setDisplayName("Port");
            port.setShortDescription("This option sets the port.");
            return new PropertyDescriptor[] {hostname, port};
        } catch (IntrospectionException ie) {
            System.err.println("Introspection exception thrown: "+ie);
            return null;
        }
    }

    public Image getIcon(int type) {
        if (type == BeanInfo.ICON_COLOR_16x16 || type == BeanInfo.ICON_MONO_16x16) {
            return Utilities.loadImage(
                    "/org/netbeans/modules/mymodule/MyModuleIcon16.gif");
        } else {
            return null;
        }
    }
}

This way you set the names of the options and their descriptions, displayed in Tools | Options. You also specify an icon which is displayed in the panel. The last missing piece is wiring these options into the UI. Again, we'll use our favourite layer.xml file:

    <folder name="UI">
        <folder name="Services">
          <folder name="IDEConfiguration">
            <folder name="ServerAndExternalToolSettings">
              <file name="org-netbeans-modules-mymodule-MyModuleSettings.shadow">
                <attr name="originalFile" stringvalue="Services/org-netbeans-modules-mymodule-MyModuleSettings.settings"/>
              </file>
            </folder>
          </folder>
        </folder>
      </folder>

Yes, the options in Tools | Options are created like this, simply via definitions in xml files. This part defines that your options will be displayed in IDE Configuration | Server And External Tools Settings. The .shadow is actually a link the original xml settings file which specifies the class implementing your Options.

And that's it - your plug-in is now plugged into Tools | Options.
Comments:

Hi Roumen, when I tried your instructions, the Source Editor complained about this line:

public static final Integer PROP_PORT = "port";

found: java.lang.String
required: java.lang.Integer

Posted by Geertjan on říjen 07, 2005 at 12:39 dop. CEST #

By the way, two other questions:
  1. Is it possible to add options to the Modern View (I used your instructions for the host and ended up with it in the Classic View, but would now like it in the Modern View).
  2. How do you change an existing system option?

Posted by Geertjan on říjen 07, 2005 at 01:29 dop. CEST #

Oops, should be String in the first case. I'll fix it.

I did not work with modern view, Hanz wrote this on NetCAT:
See NetBeans API:
http://www.netbeans.org/download/dev/javadoc/
Options Dialog SPI should help you. Feel free to ask me, if you can not find something there.

I also never tried to change an existing option, you can definitely change the option in the module which defines it... but that's probably not what you're looking for. If I have time I'll try to play with new options API.

Posted by Roumen on říjen 07, 2005 at 04:15 dop. CEST #

Hi Roman, I tried to add some options to my plugin (timesheet). I went step-by-step but something seems to be wrong. My options are not read from where ever they are stored until I open Options dialog and click on my options entry under "Server And External Tools Settings". Till than MyModuleSettings return the default settings. Could you help me?

Posted by Stefan Radacovsky on prosinec 06, 2006 at 08:12 dop. CET #

See if this helps with your persistence problem:
http://wiki.netbeans.org/wiki/view/DevFaqSystemOptionNotPersisted

Posted by Gabriel Burca on prosinec 21, 2006 at 11:54 dop. CET #

Post a Comment:
Comments are closed for this entry.
About

Roman Strobl

Search

Archives
« duben 2014
PoÚtStČtSoNe
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Today