<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!-- -*- xhtml -*- -->
  <title>Integrated Property Editors in NetBeans</title>
  <link rel="stylesheet" type="text/css" href="https://netbeans.org/netbeans.css">
  <meta name="AUDIENCE" content="NBUSER">
  <meta name="TYPE" content="ARTICLE">
  <meta name="EXPIRES" content="N">
  <meta name="developer" content="tboudreau@netbeans.org">
  <meta name="indexed" content="y">
  <meta name="description"
 content="Techniques for using property editors in NetBeans.">
        <style type="text/css">
        .tips {
            margin: 5px;
            border-style: solid;
            border-width: 2px;
            border-color: #CCFFCC;
            background-color: #F5FFF5;
            padding-top: 5px;
            padding-bottom: 5px;
            padding-left: 35px;
            padding-right: 25px;
        }
        .caveat {
            margin: 20px;
            border-style: solid;
            border-width: 2px;
            border-color: #CCAAAA;
            background-color: #EECCCC;
            padding-top: 5px;
            padding-bottom: 5px;
            padding-left: 25px;
            padding-right: 25px;
        }
        .td {
            border-style: solid;
            border-width: 1px;
            border-color: #CCCCCC;
            font-family: 'Courier New';
            background-color: #CCCCCC;
            font-weight: bold;
        }
        </style>
<!--      Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. -->
<!--     Use is subject to license terms.-->
</head>
    <body>
        <h1>Integrated Property Editors in NetBeans</h1>
        <p>The NetBeans IDE includes a visual editor for Swing user interfaces
        (UIs).  Components are controlled using property editors which
        follow the Java Beans&trade; specification.  This tutorial will show
        how to distribute components inside a NetBeans plug-in, how to 
        provide custom property editors for individual properties or an
        entire class of properties of those components;  and how to write
        property editors that are able to call into and use features of
        the NetBeans IDE.
        
        <h2>Why is this so complicated?</h2>
        <p>The Java Beans specification defines how components should interact
        with an integrated development environment (IDE), and various classes
        that both an IDE and a component vendor will use to communicate with
        the IDE and vice-versa.  The fundamental problem with the beans
        specification is that, when it was created and cast in stone, 
        <i>there were no Java IDEs</i>.  The specification tends to be in
        some cases naively defined (BeanInfo), and in other cases 
        woefully underspecified (PropertyEditor) with respect to what an IDE
        or a component will actually need to provide a good user experience.
        </p>
        <p>It is possible to create generic property editors that will integrate
        with an IDE without depending on that IDE &mdash; and where this makes
        sense, it is encouraged to do that.  However, there are many cases
        where that is not sufficient.  For example, the specification for
        <code>java.beans.PropertyEditor</code> simply allows a property 
        editor to return a <code>java.awt.Component</code> to provide a
        custom editor dialog.  In practice, that component will be shown
        to the user in a dialog - and if it is possible for the user to
        provide invalid input, good UI design dictates that the OK button
        for that dialog should be disabled when the input is not usable.
        But there is no communication path for a component to tell an IDE
        about such a situation.  Similarly, a property editor that lets the
        user supply an image needs to allow the user to choose a file on
        disk to use.  If the image is not on the classpath of the project,
        it needs to be copied into some directory where it can be found at
        runtime &mdash; but there is no way for an IDE to communicate to a
        third party property editor anything about files or directories or
        classpaths.
        </p>
        <p>For these cases, NetBeans provides APIs that fill some of the gaps
        in the beans spec.  NetBeans also provides sophisticated
        user interface controls
        that can save time and create a better user experience if used.
        <center>
            <img src="../images/tutorials/property-editors/borderCustomEditor.png" alt="Border Custom Editor"/>
            <br/>
            <i>
            NetBeans' custom editor for Borders uses NetBeans' <br/>Nodes and
            Explorer API to provide the list of available <br/>borders in an
            embedded property sheet.
            </i>
        </center>
        <h2><a name="step1">Step 1:  Creating Some Beans</a></h2>
        The first step in packaging up some components is creating some
        components, so we will start by creating a simple Java project.

        <ol class="instructions">
            <li>In NetBeans, select
                <b>File &gt; New Project</b> and choose <b>Java 
                &gt; Java Class Library</b>.  On the second page of the
                new project wizard, give the project the name
                <code>Bean</code>. Click Finish.</li>
            <li>Once the project is open, create a new Java Class called
                <code>Bean1</code> in a
                package named <code>bean</code>.</li>
            <li>Add the following code to it (it will use a class that
                does not exist yet, so don't worry about warnings for
                <code>ColorValue</code>):</li>
        </ol>
        <h3><a name="listing1">Listing 1:  Bean1.java</a></h3>
        <pre>
public class Bean1 extends JComponent {
    private ColorValue colorValue = new ColorValue (255, 235, 128);

    public ColorValue getColorValue() {
        return colorValue;
    }

    public void setColorValue(ColorValue val) {
        ColorValue old = this.colorValue;
        this.colorValue = val;
        if ((old == null) != (val == null) || old != null && !old.equals(val)) {
            firePropertyChange("colorValue", old, val);
            repaint();
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension (24, 24);
    }

    @Override
    public Dimension getMinimumSize() {
        return getPreferredSize();
    }

    @Override
    public void paint (Graphics g) {
        if (colorValue != null) {
            g.setColor(colorValue.toColor());
            g.fillRect(0, 0, getWidth(), getHeight());
        }
    }
}
        </pre>
    <h2>Creating A Class That Will Need A Custom Editor</h2>
    We will start with a fairly simple (if slightly artificial)
    class.  We need to create the
    <code>ColorValue</code> class which is the type of one of
    <code>Bean1</code>'s properties (later we will handle a much
    more complex data type requiring a more sophisticated custom
    editor).
    <ol class="instructions">
        <li>Create a new Java class, <code>bean.ColorValue</code>.</li>
        <li>Populate it as shown in <a href="#listing2">Listing 2</a>.</li>
    </ol>
    <h3><a name="listing2">Listing 2: ColorValue</a></h3>
    <pre>package bean;
import java.awt.Color;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
public class ColorValue implements Serializable {
    private final PropertyChangeSupport supp = new PropertyChangeSupport(this);
    private int red;
    private int green;
    private int blue;

    public ColorValue() {}

    public ColorValue(int red, int green, int blue) {
        if (red < 0 || red > 255) {
            throw new IllegalArgumentException("" + red);
        }
        if (green < 0 || green > 255) {
            throw new IllegalArgumentException("" + green);
        }
        if (blue < 0 || blue > 255) {
            throw new IllegalArgumentException("" + blue);
        }
        this.red = red;
        this.green = green;
        this.blue = blue;
    }

    public int getBlue() {
        return blue;
    }

    public int getGreen() {
        return green;
    }

    public int getRed() {
        return red;
    }

    public void setGreen(int green) {
        if (green < 0 || green > 255) {
            throw new IllegalArgumentException("" + green);
        }
        int old = this.green;
        this.green = green;
        if (green != old) {
            supp.firePropertyChange("green", old, green);
        }
    }

    public void setBlue(int blue) {
        if (blue < 0 || blue > 255) {
            throw new IllegalArgumentException("" + blue);
        }
        int old = blue;
        this.blue = blue;
        if (old != blue) {
            supp.firePropertyChange("blue", old, blue);
        }
    }

    public void setRed(int red) {
        if (red < 0 || red > 255) {
            throw new IllegalArgumentException("" + red);
        }
        int old = this.red;
        this.red = red;
        if (old != red) {
            supp.firePropertyChange("red", old, red);
        }
    }

    public Color toColor() {
        return new Color(red, green, blue);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null || ColorValue.class != obj.getClass()) {
            return false;
        }
        final ColorValue other = (ColorValue) obj;
        return red == other.red && green == other.green && blue == other.blue;
    }

    @Override
    public int hashCode() {
        //evenly distribute 3 byte values across 32 bits
        return red + (green << 12) + (blue << 24);
    }

    public void removePropertyChangeListener(PropertyChangeListener pl) {
        supp.removePropertyChangeListener(pl);
    }

    public void addPropertyChangeListener(PropertyChangeListener pl) {
        supp.addPropertyChangeListener(pl);
    }
}</pre>
    <h2><a name="creatingModule">Creating the Plug-In</a></h2>
    Now we need to create a NetBeans plug-in (module) which will
    do three things:
    <ol>
        <li>Integrate our class library into the IDE, so that it appears
            in the list of libraries available to users (found in
            <b>Tools &gt; Libraries</b> in the IDE).  While we could ask
            users to put the JAR for our library on the classpath of
            every project they use it in, this approach is much more
            convenient.</li>
        <li>Add <code>Bean1</code> to the Component Palette, so that
            users can simply drag the component into their user interfaces.
        </li>
        <li>Provide our property editors for our property classes and
            integrate them into the IDE.
        </li>
    </ol>
    NetBeans comes with built-in support for creating modules, so setting
    up a new module project is quite simple:
    <ol class="instructions">
        <li>Select <b>File &gt; New Project</b> in the main menu.</li>
        <li>In the New Project wizard, choose
            <b>NetBeans Modules&gt; Module</b> on the first page, then click Next.</li>
        <li>On the second page of the wizard, name the project <code>BeanLibraryModule</code>.</li>
        <li>On the third page of the wizard, enter <code>org.netbeans.demo.form.beanlib</code>
            for the <b>Code Name Base</b>, and <code>Bean Library Module</code> for the
            display name.  Check the <b>Generate XML Layer</b> checkbox and click
            <b>Finish</b>.</li>
    </ol>

    <h2><a name="requireRestart">Setting The Module To Require an IDE Restart</a></h2>
    Modules which install Java libraries &mdash; particuarly ones which add components
    to the component palette should always require a restart of the IDE.  There
    are two reasons for this:
    <p>
    <ul>
        <li><i>MS Windows File Locking</i>&mdash;The IDE can reload a module without
        restarting.  However, on the Windows platform, if something is using a
        JAR file, it will be locked at the operating system level, so updating
        the module may fail with an exception if the old JAR file cannot be
        overwritten with the new one.</li>
        <li><i>Form Editor Reloading</i>&mdash;If the user has a form open, which
        is using a component from the JAR file, the component will not be replaced
        with one from the new JAR file (this could be very complicated if the file
        is modified but not saved).  For the updated component to
        be used, we need to be sure both that the form is reloaded, and also that
        any cached class data from the JAR is discarded.</li>
    </ul>
    Causing a module to request that the IDE restart itself before it is
    installed is as simple as checking a checkbox:
    <ol>
        <li>Once the project is created, right click it and choose Properties</li>
        <li>When the <b>Project Properties</b> dialog appears, click the <b>Build &gt; Packaging</b>
            item in the category list to show the Packaging page of the dialog; check
            the <b>Needs Restart on Install</b> checkbox and click <b>OK</b> to
            save this setting.
        </li>
    </ol>

    <h2><a name="tweakBuildScript">Modifying the Plug-In's Build Script</a></h2>
    We now have a plug-in.  However, we will want it to bundle the
    <code>Bean</code> project.  So before going further, it would be useful to
     do the following:
    <ol>
        <li>Modify the module's build script to recompile the Bean project &mdash;
            this way, the module will always contain the latest version of the
            project</li>
        <li>Modify the build script to copy the Bean project into the place
            it needs to be to bundle <code>Bean.jar</code> into our module.</li>
    </ol>
    Doing these things involves overriding two targets in our module project's
    build script.  Ant supports a crude sort of target inheritance, in which
    we replace a target from one build script, but call the original target by
    referring to <code>[projectname].[targetname]</code> (the project name in
    this case is the name defined in the <code>&lt;project&gt;</code> tag at the
    top of any Ant build script).
    <ol class="instructions">
        <li>Open the build script by expanding the module project in the <b>Projects</b>
            tab in the IDE, and the <b>Important Files</b> node under it, and
            double clicking the <b>Build Script</b> node.  This corresponds to
            the file <code>build.xml</code> in the <code>BeanLibraryModule</code>
            directory which is the root of our module project.</li>
        <li>Add the code found in <a href="listing3">Listing 3</a> to the build
            script, below the line <code>&lt;import file=&quot;nbproject/build-impl.xml&quot;/&gt;</code>.
    </ol>
    <h3><a name="listing3">Listing 3: Module Build Script Changes</a></h3>
<pre>&lt;target name=&quot;build-init&quot; depends=&quot;harness.build-init&quot;&gt;
    &lt;echo&gt;Rebuilding Bean JAR&lt;/echo&gt;
    &lt;ant antfile=&quot;../Bean/build.xml&quot; target=&quot;jar&quot; inheritall=&quot;false&quot; inheritrefs=&quot;false&quot;/&gt;
    &lt;mkdir dir=&quot;release/libs&quot;/&gt;
    &lt;copy file=&quot;../Bean/dist/Bean.jar&quot; todir=&quot;release/libs&quot;/&gt;
&lt;/target&gt;

&lt;target name=&quot;clean&quot; depends=&quot;projectized-common.clean&quot;&gt;
    &lt;echo&gt;Cleaning and deleting copy of Bean JAR&lt;/echo&gt;
    &lt;ant antfile=&quot;../Bean/build.xml&quot; target=&quot;clean&quot; inheritall=&quot;false&quot; inheritrefs=&quot;false&quot;/&gt;
    &lt;delete file=&quot;${basedir}/release/libs/Bean.jar&quot;/&gt;
&lt;/target&gt;</pre>

    <p class="tips">
        Most of the targets in the <code>build.xml</code> for a module project
        are in other files &mdash; specifically, in <code>nbproject/build-impl.xml</code>
        and in <code>$HARNESS/build.xml</code> and <code>$HARNESS/common.xml</code>
        (<code>$HARNESS</code> is a directory under the copy of NetBeans you
        are building against, which may or may not be your IDE).
        To find out what file a target you are calling or overriding is in,
        find the <code>build.xml</code> in the <b>Files</b> tab in the IDE.
        Expand its node and you will see all of the targets (even ones in
        other files).  Right click the
        target you are wondering about and choose <b>Open</b> to open the
        file which contains that target in the IDE.  The path on disk to the
        file will be shown in the tooltip of its tab in the editor.
    
        <p>This code will build the <code>Bean</code> project, and copy the resulting
    JAR file to <code>BeanLibraryModule/release/libs</code>.  The build script
    will bundle anything under the <code>release</code> subdir of a module into
    the NBM file you will deliver to your users (for example, via an update
    server found via <b>Tools &gt; Plugins</b>).
    <p/>
    At this point, it is a good time to make sure everything is working correctly.
    You can test this by right clicking <code>BeanLibraryModule</code> in the
    <b>Projects</b> tab, and choosing <b>Build</b> from the popup menu (or
    by pressing F11).
    <p/>

    <h2>Adding Bean.jar to Tools &gt; Libraries</h2>
    Now we need to add some metadata to our module &mdash; no code yet &mdash; to
    make <code>Bean.jar</code> appear in the list of libraries for users who
    have installed our module.  This involves two steps:
    <ol class="instructions">
        <li>Open the module's <i>layer file</i> &mdash; you can find it under
            the <b>Important Files</b> node below the module project's node in
            the <b>Projects</b> tab (if you don't see it, you did not check the
            <b>Generate XML Layer</b> button when you created the module project).
            This file provides declarative metadata to NetBeans at runtime.  One
            of the things it can do is tell NetBeans about a library a module
            is installing.</li>
        <li>Between the <code>&lt;filesystem&gt;</code> tags, add the XML from
            <a href="#listing4">listing 4</a>.</li>
    </ol>
 
    <h3><a name="listing4">Listing 4:  Adding Library Metadata to a Module's XML Layer</a></h3>
<pre>
&lt;folder name=&quot;org-netbeans-api-project-libraries&quot;&gt;
    &lt;folder name=&quot;Libraries&quot;&gt;
        &lt;file name=&quot;Bean.xml&quot; url=&quot;Bean.xml&quot;/&gt;
    &lt;/folder&gt;
&lt;/folder&gt;
</pre>
    The <code>url</code> attribute of the <code>file</code> tag is important &mdash;
    the XML we have entered defines a <i>virtual file</i> &mdash; but a file name
    is usually useless without some content.  The URL attribute is a path, relative
    to the layer file, in the location where it really lives on disk.  The next
    step is to actually create a file called <code>Bean.xml</code>.
    <ol class="instructions">
        <li>With the layer XML file open, press Ctrl-Shift-1 (Command-Shift-1 on
            Macintosh) to reveal the file, inside the package
            <code>org.netbeans.demo.form.beanlib</code> in the module project's
            source code.</li>
        <li>Right click that package, and choose <b>New &gt; Other</b>.  In the
            New File Wizard which opens, choose <b>XML &gt; XML Document</b>.</li>
        <li>Name the file <code>Bean</code> on the second page of the
            wizard and click <b>Finish</b> to create the file.</li>
        <li>Populate the file with the XML content in <a href="#listing5">listing 5</a>.</li>
    </ol>
    <h3><a name="listing5">Listing 5:  An XML Library Definition for Bean.jar</a></h3>
    <pre>
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE library PUBLIC &quot;-//NetBeans//DTD Library Declaration 1.0//EN&quot; &quot;https://netbeans.org/dtds/library-declaration-1_0.dtd&quot;&gt;
&lt;library version=&quot;1.0&quot;&gt;
    &lt;name&gt;Bean&lt;/name&gt;
    &lt;type&gt;j2se&lt;/type&gt;
    &lt;localizing-bundle&gt;org.netbeans.demo.form.beanlib.Bundle&lt;/localizing-bundle&gt;
    &lt;volume&gt;
        &lt;type&gt;classpath&lt;/type&gt;
        &lt;resource&gt;jar:nbinst://org.netbeans.demo.form.beanlib/modules/ext/Bean.jar!/&lt;/resource&gt;
    &lt;/volume&gt;
    &lt;volume&gt;
        &lt;type&gt;src&lt;/type&gt;
    &lt;/volume&gt;
    &lt;volume&gt;
        &lt;type&gt;javadoc&lt;/type&gt;
    &lt;/volume&gt;
&lt;/library&gt;
    </pre>
    <div class="tips">
    Note that there are placeholders in this file for Javadoc documentation
    and source files.  If you want to include these later, just create targets
    in <code>Bean/build.xml</code> to build and zip the javadoc and sources
    into zip files, and modify <code>BeanLibraryModule</code> to call those
    targets in the Bean project and copy the additional files into the
    same directory as <code>Bean.jar</code>;  then add <code>&lt;resource&gt;</code>
    tags similar to the one already in this file, but pointing to the zip files.
    Such files are helpful for users who want instantly available documentation,
    or wish to step through your component's code in a debugger.
    </div>

    <h2>Localizing Library and Other Names</h2>
    All user-visible strings in NetBeans are localized &mdash; put into
    resource-bundle files, so they can be translated into other human languages.
    Things which are installed declaratively via <code>layer.xml</code> files
    are no exception.  You may have noticed that a <i>localizing bundle</i>
    is mentioned in some of the XML we have already entered.  This is a pointer
    to a file named <code>Bundle.properties</code>, which should live in the
    package <code>org.netbeans.demo.form.beanlib</code> alongside our other
    files.  If it does not exist, create it as follows:
    <ol class="instructions">
        <li>Right click the package <code>org.netbeans.demo.form.beanlib</code>
            and choose <b>New &gt; Other</b> from the popup menu.</li>
        <li>Choose <b>Other &gt; Properties File</b> on
            the first step of the New File Wizard and click Next.</li>
        <li>On the second step of the wizard, name the file <code>Bundle</code>
            and click <b>Finish</b>.</li>
        <li>Add the content in <a href="#listing6">listing 6</a> to the
        newly created resource bundle file (the content includes entries
        for files we are about to create in order to add <code>Bean1</code> to
        the Component Palette).</li>
    </ol>
    <h3><a name="listing6">Listing 6:  Localized Names for Library and Component Palette Items</a></h3>
    <pre>
Bean=Bean
FormDesignerPalette/Bean=Beans!
NAME_bean-Bean1=The Bean
HINT_bean-Bean1=This is a Bean
    </pre>

    At this point, we have a working module to bundle Bean as a library.
    To try it out, right click the Bean Library Module project and choose
    <b>Run</b>.  This will start another copy of NetBeans.  When it is started,
    look for your library in the library manager dialog that opens when you
    select <b>Tools &gt; Libraries</b> from the main menu.

    <h2>Including <code>Bean.jar</code> on the Module's Class Path</h2>
    We are bundling the JAR file as a library.  However, if we want property
    editors which can talk to both our Java Bean classes and to NetBeans itself,
    we will need to put <code>Bean.jar</code> onto our module's classpath as
    well.  NetBeans is very strict about what JARs a module can see classes
    from, and by default, a library is for use in the projects a user creates,
    not for loading in to the VM NetBeans is running in.  So we need to
    explicitly include <code>Beans.jar</code> in our module's classpath if we
    want to be able to use classes from it in our module &mdash; and if we want
    to provide <i>NetBeans-aware property editors</i> we need to do that.

    <p class="tips">
        Not everybody needs property editors that interact with
        the IDE beyond the very limited ways the Java Beans specification allows.
        If you are writing ordinary property editors, you can simply skip the rest of this step, then 
        follow the later steps to add your beans to the component
        palette and stop there:
        <ol>
            <li>Create another Java Class Library project called BeanEditors.</li>
            <li>Put the Beans project on its classpath.</li>
            <li>Create the <code>beans</code> package in the new project.</li>
            <li>Write your properties (and optionally BeanInfo) there.</li>
            <li>Add another <code>&lt;resource&gt;</code> entry to <code>Bean.xml</code>
            below the first one, which refers to <code>BeanEditors.jar</code></li>
            <li>Modify the module project's build script to build that project.
                too, and copy <code>BeanEditors.jar</code> to <code>release/libs</code>.</li>
        </ol>

        <p>To add <code>Bean.jar</code> to the classpath of <i>classes in your module</i>,
    do the following:
    <ol class="instructions">
        <li>Under the <b>Important Files</b> node under the Bean Library Module
        project, double click the node <b>Project Metadata</b> to open the
        project's <code>nbproject/project.xml</code> file in the editor.</li>
        <li>Add the code in <a href="#listing7">listing 7</a> to the bottom
            of this file, just above the closing <code>&lt;/data&gt;</code> tag.</li>
        <li>Build the Bean Library Module project, to ensure that the JAR is
            where it needs to be.</li>
        <li>Shut down and restart the IDE (module projects are not terribly
        intelligent about rescanning the classpath when the project metadata
        is manually modified, so you need to do this to have code-completion
        and parsing work in the editor later, when you use
        classes from <code>Bean.jar</code> in your
        module. This may be improved in future release of NetBeans).</li>
    </ol>
    <h3><a name="listing7">Listing 7:  Adding Bean.jar to our Module's Classpath</a></h3>
    <pre>
&lt;class-path-extension&gt;
    &lt;runtime-relative-path&gt;ext/Bean.jar&lt;/runtime-relative-path&gt;
    &lt;binary-origin&gt;../Bean/dist/Bean.jar&lt;/binary-origin&gt;
&lt;/class-path-extension&gt;</pre>

    <div class="tips">
        The &ldquo;runtime relative path&rdquo; is the path to Bean.jar from
        the location of the module JAR at runtime.  The NBM file
        which is created when you right click the module project and choose
        <b>Create NBM</b> is unpacked onto disk when the user installs it.
        You can build the NBM and then expand in the <b>Files</b> tab in the
        IDE to browse its contents.  You will find the module JAR under the
        <code>modules/</code> folder in the NBM.  You will also find
        <code>modules/ext/Bean.jar</code> there &mdash; Bean.jar is added to
        the module's classpath using the standard Java mechanism of including
        <code>Class-Path:  ext/Bean.jar</code> in the module's JAR manifest.
    </div>

    <h2>Adding Bean1 to the Component Palette</h2>
    We have our library embedded in our module &mdash; next we need to put
    our component on the Component Palette, so users will be able to drag
    and drop it into their user interfaces.  Doing that is quite simple, and
    very similar to the way we added <code>Bean.jar</code> as a library &mdash;
    it will again involve editing the <code>layer.xml</code> file, adding a
    reference to an external XML file and then creating that file.
    <ol class="instructions">
        <li>Open the <code>layer.xml</code> file, either by clicking
            <b>Important Files &gt; XML Layer</b> under your project,
            or the node for <code>layer.xml</code> in the package
            <code>org.netbeans.demo.form.beanlib</code>.</li>
        <li>Add the code in <a href="#listing8">listing 8</a> after the
            initial <code>&lt;filesystem&gt;</code> tag.</li>
        <li>Create a new XML file called <code>Bean1_paletteItem.xml</code>
            next to the <code>layer.xml</code> file in the same package.</li>
        <li>Replace the new XML file's contents with the XML code in
            <a href="#listing9">listing 9</a>.
    </ol>

    <h3><a name="listing8">Listing 8:  Adding a <code>palette_item</code> file to the layer.xml</a></h3>
    <pre>
&lt;folder name=&quot;FormDesignerPalette&quot;&gt;
    &lt;folder name=&quot;Bean&quot;&gt;
        &lt;attr name=&quot;SystemFileSystem.localizingBundle&quot; stringvalue=&quot;org.netbeans.demo.form.beanlib.Bundle&quot;/&gt;
        &lt;file name=&quot;Bean1.palette_item&quot; url=&quot;Bean1_paletteItem.xml&quot;/&gt;
    &lt;/folder&gt;
&lt;/folder&gt;</pre>
    <h3><a name="listing9">Listing 9:  XML File Defining a Component on the Palette</a></h3>
    <pre>
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;palette_item version=&quot;1.0&quot;&gt;
  &lt;component classname=&quot;bean.Bean1&quot;/&gt;
  &lt;description localizing-bundle=&quot;org.netbeans.demo.form.beanlib.Bundle&quot;
               display-name-key=&quot;NAME_bean-Bean1&quot;
               tooltip-key=&quot;HINT_bean-Bean1&quot; /&gt;
  &lt;classpath&gt;
    &lt;resource type=&quot;library&quot; name=&quot;Bean&quot;/&gt;
  &lt;/classpath&gt;
&lt;/palette_item&gt;
    </pre>

    <P>At this point, the work of embedding our library and our component is done.
    Run the module now to try out the result &mdash; create a new project in
    the copy of NetBeans that starts, then use <b>New &gt; JPanel Form</b> to
    show the form editor (aka &ldquo;Matisse&rdquo;).  There will be a new
    category, <b>Beans!</b> on the Component Palette.  Expand it, and you will
    see <code>Bean1</code>, listed as <b>The Bean</b> (these are the strings
    we defined in our <code>Bundle.properties</code> file).  Drag it onto the
    form to use it.
    <p>Notice also that, after you add a <code>Bean1</code> to a form, if you
    expand the <b>Libraries</b> node under the project, the <code>Bean</code>
    library has automatically been added to the project's classpath.

    <p class="tips">
        The Java Beans specification allows a <code>BeanInfo</code>
        class for a component to define a localized name for it, along with
        icons.  In the example above, we defined the localized name in the
        <code>palette_item</code> file's definition and the <code>Bundle.properties</code>
        file.  You can use either one (just leave out the line about the resource
        bundle in the XML file to use the BeanInfo);  if you are going
        to need a <code>BeanInfo</code> anyway, you can just define it there.
        However, since they are Java classes, BeanInfos use memory and are
        an inefficient way to define this sort of thing.  If possible, avoid
        having a <code>BeanInfo</code> and just use this mechanism.
        <p/>
        If you want to provide icons via the <code>palette_item</code> XML file,
        you can do that too &mdash; just add the following lines inside the
        <code>&lt;palette_item&gt;</code> tags in the file, replacing the file
        name with a .gif or .png file name, and the path with the path in your module
        to the package they are in:
        <pre>&lt;icon16 urlvalue=&quot;nbres:/org/netbeans/modules/form/beaninfo/awt/panel.gif&quot; /&gt;
&lt;icon32 urlvalue=&quot;nbres:/org/netbeans/modules/form/beaninfo/awt/panel32.gif&quot; /&gt;</pre>

    <h2>Creating A Property Editor</h2>
    Now we are ready to create a property editor.  We will put our editors in
    another package, <code>org.netbeans.demo.form.beanlib.editors</code> &mdash;
    in accordance with the Java Beans specification, that package will be registered
    with <code>java.beans.PropertyEditorManager</code>.  We don't need
    <code>PropertyEditorManager</code> to be able to find other classes that are part
    of our module, but are not our property editors or classes our property
    editors use.  So keeping unrelated classes invisible to our property editors
    is good sense both from a perfomance and a security perspective.
    <ol class="instructions">
        <li>Right-click the <code>org.netbeans.demo.form.beanlib.editors</code> package
            and choose <b>New &gt; Java Class</b>.</li>
        <li>When the New File Wizard opens, name the class <code>ColorValueEditor</code>.</li>
        <li>Replace the template code that initially appears in the new Java file with
            the code in <a href="#listing10">listing 10</a>.
    </ol>
    <h3><a name="listing10">Listing 10:  A PropertyEditor for ColorValue Objects</a></h3>
    <pre>package org.netbeans.demo.form.beanlib.editors;
import bean.ColorValue;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyEditor;
import org.openide.explorer.propertysheet.ExPropertyEditor;
import org.openide.explorer.propertysheet.PropertyEnv;
public class ColorValueEditor implements PropertyEditor, ExPropertyEditor {
    private ColorValue value;
    public void setValue(Object o) {
        this.value = (ColorValue) o;
    }

    public Object getValue() {
        return value;
    }

    public boolean isPaintable() {
        return false;
    }

    public void paintValue(Graphics grphcs, Rectangle rctngl) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getJavaInitializationString() {
        return "new ColorValue(" + value.getRed() + ',' +
                value.getGreen() + ',' + value.getBlue() + ')';
    }

    public String getAsText() {
        return "" + value.getRed() + ',' + value.getGreen() + ',' +
                value.getBlue();
    }

    public void setAsText(String string) throws IllegalArgumentException {
        String[] rgb = string.split(",");
        if (rgb == null || rgb.length != 3) {
            throw new IllegalArgumentException ("Should be in format " +
                    "'red,green,blue'");
        }
        try {
            int red = Integer.parseInt(rgb[0].trim());
            int green = Integer.parseInt(rgb[1].trim());
            int blue  = Integer.parseInt(rgb[2].trim());
            setValue (new ColorValue(red, green, blue));
        } catch (NumberFormatException nfe) {
            throw new IllegalArgumentException(nfe);
        }
    }

    public String[] getTags() {
        return null;
    }

    public Component getCustomEditor() {
        return null;
    }

    public boolean supportsCustomEditor() {
        return false;
    }

    private final PropertyChangeSupport supp = new PropertyChangeSupport(this);
    public void addPropertyChangeListener(PropertyChangeListener pl) {
        supp.addPropertyChangeListener(pl);
    }

    public void removePropertyChangeListener(PropertyChangeListener pl) {
        supp.removePropertyChangeListener(pl);
    }

    private PropertyEnv env;
    public void attachEnv(PropertyEnv pe) {
        env = pe;
    }
}
    </pre>

    <h2>Registering The Property Editor Package</h2>
    <p>We now have a property editor for <code>ColorValue</code> objects.  The next
    step is to register our property editor package, so that, when our module is
    run in the IDE, <code>java.beans.PropertyEditorManager</code> can find our
    editor and it will be used in the Property Sheet of the Form Editor.
    <p>While most of the time, the way you install things in NetBeans, so that the IDE
    can find your module's classes at runtime, is declarative &mdash; using the
    <code>layer.xml</code> file and similar mechanisms &mdash; <code>PropertyEditorManager</code>
    is not part of NetBeans, it is part of the JDK.  It expects registration
    to be done programmatically, via Java code that runs during IDE startup.
    Running code during startup is generally to be avoided, since it means the
    user will be looking at the startup splash-screen for longer, but in this
    case there is no other way.
    <p/>
    To register our property editor, we need to create a subclass of
    <code>org.openide.modules.ModuleInstall</code>,
    and add a reference to it to our module's JAR manifest.  Fortunately, there
    is a file template built into NetBeans' module-writing tools that will take
    care of creating the subclass and adding the manifest entry &mdash; we can use
    that and then just add the code we need to the resulting <code>ModuleInstall</code>.
    To do that:
    <ol class="instructions">
        <li>Right click the <code>org.netbeans.demo.form.beanlib</code> package and
        choose <b>New &gt; Other</b> from the popup menu.</li>
        <li>In the New File Wizard, choose <b>Module Development &gt; Module Installer</b>
            and click <b>Next</b>, then click <b>Finish</b>.  A Java file called
            <code>Installer</code> will be created in the package.</li>
        <li>Replace the <code>restored()</code> method with the contents of
            <a href="#listing11">listing 11</a></li>
    </ol>
    <h3><a name="listing11">Listing 11: Registering The Property Editors Package At IDE Startup</a></h3>
    <pre>
public void restored() {
    String[] old = PropertyEditorManager.getEditorSearchPath();
    List &lt;String&gt; l = new ArrayList&lt;String&gt;(Arrays.asList(old));
    l.add ("org.netbeans.demo.form.beanlib.editors");
    PropertyEditorManager.setEditorSearchPath(l.toArray(new String[l.size()]));
}</pre>
    <div class="tips">
        <p><code>java.beans.PropertyEditorManager</code> uses a naming convention
        to recognize property editors:  It expects the class name of an editor
        for a type to be the name of the class it edits plus &quot;Editor&quot;
        (i.e. the editor class for a ColorValue must be called ColorValueEditor).
        PropertyEditorManager also allows you to register a specific
        editor class to edit a specific class.  The code above would look like
        <code>PropertyEditorManager.registerEditor (ColorValue.class, ColorValueEditor.class)</code>
        if we took that approach.
        <p>Package name based registration has the
        advantage that neither the ColorValue nor the ColorValueEditor class
        needs to be loaded into the VM unless the user actually uses it.
    </div>

    <h2>NetBeans Form Editor Classloader Black Magic</h2>
    <p>At this point we are almost ready to run our module with our property
    editor.  There is one bit of arcana left to take care of.  As mentioned
    earlier, NetBeans does various tricks with classloaders &mdash; in particular,
    limiting classes a module can see to only those ones it says it needs
    access to.
    <p>A Swing GUI and its libraries are classes that belong to the user &mdash; they
    are not parts of NetBeans.  The form editor takes a similar approach &mdash;
    Java classes used in a Swing UI <i>are</i> loaded into the Java Virtual Machine
    NetBeans is running in;  however, they are loaded in their own classloader,
    which normally does not allow random components access to classes from
    a module.  This has two beneficial effects:
    <ol class="instructions">
        <li>A foreign Swing component cannot interfere with the operation of the
            rest of the IDE, just because a user dropped it on a form.</li>
        <li>Misbehaving or memory-leaking components can be discarded when the
            form is closed and the classloader it used is discarded &mdash;
            limiting the potential damage a buggy component can do.</li>
    </ol>
    <p>We have already set up the classpath so that our module can see classes
    from <code>Bean.jar</code>.  We need to set up the reverse situation &mdash;
    allow our properties to call into classes in our module and the rest of
    NetBeans when they are loaded inside the sandbox of the classloader the
    form editor uses for loading the user's components.
    <p>This is accomplished via a bit of black magic with the form editor's classloader.
    The form editor allows us to define a special text file in our <code>layer.xml</code>
    file, which contains a list of classes and/or packages that should be visible
    to components living inside a Swing form.  To accomplish this:
    <ol class="instructions">
        <li>Open <code>layer.xml</code> again in the text editor.</li>
        <li>Add the XML fragment from <a href="#listing12">listing 12</a> before
        the closing <code>&lt;/filesystem&gt;</code> tag.</li>
        <li>Right click the <code>org.netbeans.demo.form.beanlib</code> package,
            and choose <b>New &gt; Other</b>.</li>
        <li>In the New File Wizard, choose <b>Other &gt; Empty File</b> and click
            <b>Next</b>.</li>
        <li>In the second page of the New File Wizard, name the file <code>BeanClasses.txt</code>
            (note that because we are using the <b>Empty File</b> template, we
            need to specify the file extension &mdash; normally you do not do this
            or you end up with file names such as <code>Foo.xml.xml</code>).</li>
        <li>Paste the contents of <a href="#listing13">listing 13</a> into the
            new text file.</li>
    </ol>
    <h3><a name="listing12">Listing 12:  Registering Classes That Should Be Visible in layer.xml</a></h3>
    <pre>
&lt;folder name=&quot;org-netbeans-modules-form&quot;&gt;
   &lt;folder name=&quot;classloader&quot;&gt;
       &lt;folder name=&quot;system&quot;&gt;
            &lt;file name=&quot;BeanClasses.txt&quot; url=&quot;BeanClasses.txt&quot;/&gt;
        &lt;/folder&gt;
   &lt;/folder&gt;
&lt;/folder&gt;</pre>
    <p class="tips">
        If your property editors or components also need to be able
        to see classes or resources (such as images) that are part of
        the user's project, you can register the
        class list in the folder <code>system_with_project</code> instead of
        <code>system</code>.  If some do and some do not, register two lists,
        including only those that really need to see classes from the user's
        project in <code>system_with_project</code>.
    

    <h3><a name="listing13">Listing 13:  Listing Module Classes That Should Be Visible to Components in the Form Editor</a></h3>
    <pre>org.netbeans.demo.form.beanlib.editors.**
bean.**
    </pre>
    Now at last we have working property editors which are registered by our
    module.  You can run the module project, add a <code>Bean1</code> to a
    Swing form, and the property <code>colorValue</code> will use our property
    editor.
    <p/>
    <p class="tips">This file can list individual classes, or it can list packages
    including all subpackages of those classes by using the suffix <code>**</code>,
    or limit the search to only the one specified package but using the
    suffix <code>*</code>.
    The next step is to create a custom editor that will interact with the
    IDE, controlling its (NetBeans-provided) OK button.

    <h2>Adding A Custom Editor</h2>
    To really interact with the IDE, we should add support for a custom
    (pop-up window) editor for our <code>ColorValue</code> property.
    To do that:
    <ol class="instructions">
        <li>Right-click the <code>org.netbeans.demo.form.beanlib.editors</code> package
        and choose <b>New &gt; JPanel Form</b> from the popup window.</li>
        <li>In the New File Wizard that opens, name the file <code>ColorValueCustomEditor</code>.</li>
        <li>In the newly created JPanel form, add the following components
            from the Component Palette, arranging the UI as shown in
            <a href="#figure2">figure 2</a> and setting the variable names
            as shown below (to set the name, slow-double-click the name of
            each component in the <b>Inspector</b> window, then type the new 
            name;  component type shown in parentheses):
            <p><center>
            <a name="figure2"><img src="../images/tutorials/property-editors/colorValueCustomEditorUI.png" alt="Color Value Custom Editor"></a><br/>
                <i>Figure 2: Color Value Custom Editor User Interface</i>
                <p>
                <table>
                <tr>
                    <td class="td">redLabel (JLabel)</td><td class="td">redSlider (JSlider)</td><td class="td">redValue (JLabel)</td>
                </tr>
                <tr>
                    <td class="td">greenLabel (JLabel)</td><td class="td">greenSlider (JSlider)</td><td class="td">greenValue (JLabel)</td>
                </tr>
                <tr>
                    <td class="td">blueLabel (JLabel)</td><td class="td">blueSlider (JSlider)</td><td class="td">blueValue (JLabel)</td>
                </tr>
                <tr>
                    <td class="td">intLabel (JLabel)</td><td class="td" colspan="2" align="center">intValue (JTextField)</td>
                </tr>
                <tr>
                    <td class="td" colspan="3" align="center">sample (JLabel)</td>
                </tr>
            </table>
                    <i>Table 1:  Component Variable Names and Types in ColorValueCustomEditor</i>
            </center>
        </li>
        <li>Set the property <b>Opaque</b> to true on the property sheet for
            <code>sample</code>.</li>
        <li>Select all (shift-click) of the JSliders in the form editor, and set
        their <code>maximum</code>
        property to <code>255</code>.</li>
        <li>Replace the constructor of <code>ColorValueCustomEditor</code> with the
            content of <a href="#listing14">listing 14</a>.
        <li>Change the class signature of <code>ColorValueCustomEditor</code> to look
            like <a href="#listing15">listing 15, implementing <code>ChangeListener</code>
            and <code>DocumentListener</code></a>.</li>
        <li>Add the code in <a href="listing16">listing 16</a> to
            <code>ColorValueCustomEditor</code> to implement the listener
            interfaces and handle events.</li>
    </ol>
    <h3><a name="listing14">Listing 14:  ColorValueCustomEditor Constructor</a></h3>
    <pre>
    private final ColorValueEditor ed;
    public ColorValueCustomEditor(ColorValueEditor ed, PropertyEnv env) {
        initComponents();
        ColorValue cv = (ColorValue) ed.getValue();
        if (cv != null) {
            Color c = cv.toColor();
            setColor(c);
            intValue.setText(c.getRGB() + "");
        }
        env.setState(PropertyEnv.STATE_VALID);
        this.ed = ed;
        redSlider.getModel().addChangeListener(this);
        greenSlider.getModel().addChangeListener(this);
        blueSlider.getModel().addChangeListener(this);
        intValue.getDocument().addDocumentListener(this);
    }</pre>

    <h3><a name="listing15">Listing 15:  Changing the Class Signature of ColorValueCustomEditor to Implement Listeners</a></h3>
    <pre>final class ColorValueCustomEditor extends javax.swing.JPanel implements ChangeListener, DocumentListener {</pre>

    <h3><a name="listing16">Listing 16:  Listener Interface Implementation for ColorValueCustomEditor</a></h3>
    <pre>
    private ColorValue getPropertyValue() {
        return new ColorValue(redSlider.getValue(), greenSlider.getValue(),
                blueSlider.getValue());
    }

    private boolean inUpdate;
    public void stateChanged(ChangeEvent ce) {
        if (inUpdate) {
            return;
        }
        inUpdate = true;
        try {
            redValue.setText(redSlider.getValue() + "");
            greenValue.setText(greenSlider.getValue() + "");
            blueValue.setText(blueSlider.getValue() + "");
            ColorValue v = getPropertyValue();
            Color c = v.toColor();
            intValue.setText(c.getRGB() + "");
            sample.setBackground(c);
            ed.setValue(v);
        } finally {
            inUpdate = false;
        }
    }

    public void insertUpdate(DocumentEvent de) {
        changedUpdate(de);
    }

    public void removeUpdate(DocumentEvent de) {
        changedUpdate(de);
    }

    void setColor (Color c) {
        boolean old = inUpdate;
        inUpdate = true;
        try {
            redSlider.setValue(c.getRed());
            greenSlider.setValue(c.getGreen());
            blueSlider.setValue(c.getBlue());
        } finally {
            inUpdate = old;
        }
    }

    public void changedUpdate(DocumentEvent de) {
        if (!inUpdate) {
            try {
                int val = Integer.parseInt(intValue.getText().trim());
                setColor(new Color(val));
            } catch (NumberFormatException e) {
                PropertyEnv env = ed.env;
                if (env != null) {
                    env.setState(PropertyEnv.STATE_VALID);
                }
            }
        }
    }
    </pre>

    Now we just need to modify <code>ColorValueEditor</code> to actually
    create a <code>ColorValueCustomEditor</code>.  To do that:
    <ol class="instructions">
        <li>Update the <code>supportsCustomEditor()</code> and <code>getCustomEditor()</code>
            to look like <a href="#listing17">listing 17</a></li>
    </ol>
    <h3><a name="listing17">Listing 17:  Creating Our Custom Editor</a></h3>
    <pre>
    public Component getCustomEditor() {
        return new ColorValueCustomEditor(this, env);
    }

    public boolean supportsCustomEditor() {
        return true;
    }</pre>

    At this point, we are ready to run the project, and when you click on the
    [...] button for the <code>colorValue</code> property of an instance of
    <code>Bean1</code> on your form, our newly finished custom editor will open.
    Notice that if you type an invalid number in the text area, the
    OK button will become disabled.

    <h3>What ColorValueEditor Does</h3>
    <p>You may have noticed that <code>ColorValueEditor</code> implements a
    NetBeans interface, <code>org.openide.explorer.propertysheet.ExPropertyEditor</code>,
    in addition to the standard JDK <code>PropertyEditor</code> interface.
    This interface, or more importantly the <code>PropertyEnv</code> object that
    is passed to it is the path for our property editor to escape the
    prison of the Java Beans spec and interact with the environment (the IDE)
    that instantiated it.
    <p><code>PropertyEnv</code> is an enigmatic little class, but it offers a lot
    of power.  In our case, we are using it very simply, just to let our
    custom editor control the OK button of the dialog it appears in.  To do that,
    we call <code>env.setState(PropertyEnv.STATE_INVALID)</code> to disable the
    OK button, and <code>env.setState(PropertyEnv.STATE_VALID)</code> to re&euml;nable
    it.  Here are some of the other things we could do with it:
    <ul>
        <li>Delay figuring out if the user's input is good or not until the
            user presses enter, by calling <code>env.setState(PropertyEnv.STATE_NEEDS_VALIDATION)</code> and
            attaching a <code>VetoableChangeListener</code> which can veto a change
            to <code>STATE_VALID</code> which will happen when the user presses
            OK</code></li>
        <li>Get the <code>Node.Property</code> object which created the property
            editor and represents the property being useful, using <code>env.getFeatureDescriptor()</code>.
            This is useful for passing hints to the property sheet about how an
            editor should behave when in the property sheet.  Two useful hints are
            <ul>
                <li>Call <code>env.getFeatureDescriptor().setValue("canEditAsText", Boolean.FALSE)</code>
                    to make the property non-editable inside the property sheet
                    (so the only way to change the property is to open the custom
                    editor).
                </li>
                <li>Call <code>env.getFeatureDescriptor().setValue("suppressCustomEditor", Boolean.TRUE)</code>
                    from a <code>PropertyEditor</code> subclass, to hide the
                    [...] custom editor button on a property that would otherwise
                    have one.
                </li>
            </ul>
        </li>
        <li>Register an <code>InplaceEditor.Factory</code> which can provide the UI
        component that is shown in the property sheet when the user edits the property
        without opening a custom editor (a tutorial on how to do that can
        <a href="https://platform.netbeans.org/tutorials/nbm-property-editors.html">be found here</a>)</li>
        <li>Get the Node for the file being edited like this:
            <pre>
Node n = null;
for (Object o : env.getBeans()) {
  if (o instanceof Node) {
    n = (Node) o;
    break;
  }
}
            </pre>
            and use that to
            <ul>
                <li>Get the file that is being edited &mdash; <code>n.getLookup().lookup(DataObject.class).getPrimaryFile()</code></li>
                <li>Find the project that owns the file being edited and interrogate its classpath (for example,
                    to list possible directories the user might want to save an icon file 
                    to):<pre>FileObject fo = n.getLookup().lookup(DataObject.class).getPrimaryFile();
Project project = FileOwnerQuery.getOwner(fo);
if (project != null) } {
   ClassPathProvider provider = project.getLookup().lookup(ClassPathProvider.class);
   ...</pre>
                </li>
            </ul>
        </li>
    </ul>
    <div class="caveat">
        Be aware that <code>attachEnv()</code> may be called more than once for
        your property editor.  To make sure you are using the right instance of
        <code>PropertyEnv</code>, store the value from the most recent call in
        a field of your property editor, and pass that to the custom editor.
    </div>


    <h2>Writing XML Instead Of Serializing</h2>
    <p>The last thing we may want to do is more about plumbing than anything the
    user sees directly:  When you are editing a Swing form in the NetBeans Form
    Editor, you are really editing two files (though you only see the Java file
    in the projects tab).  The form editor is really an editor for an invisible (in NetBeans)
    XML file that sits next to the Java source file.  The form editor is really
    an editor of that XML file.  Whenever you make a change in the form editor,
    the data about how components are positioned and their properties
    is saved in that file.  That file is then used to generate the
    <code>initComponents()</code> method and other code inside the non-editable
    blue code blocks in your Java source.  Whenever the XML file changes (because
    you made a change in the form editor and saved the file), those blue
    <i>guarded blocks</i> are regenerated into the Java source file.
    <p>It is worth taking a look at the <code>.form</code> file after you have
    modified a <code>ColorValue</code> and saved the form (make sure you save it!).
    To do this, you will need to go outside of NetBeans and use a text
    editor (if on Windows,
    use a text editor that understands lines that end with just a carriage
    return character &mdash; WordPad, usually located in <code>C:\Program Files\Windows NT\Accessories</code>
    on Windows will do).  What you will see is something like this:
    <pre>&lt;Property name=&quot;colorValue&quot; type=&quot;bean.ColorValue&quot; editor=&quot;org.netbeans.demo.form.beanlib.editors.ColorValueEditor&quot;&gt;
  &lt;SerializedValue value=&quot;-84,-19,0,5,115,114,0,15,98,101,97,110,46,67,
                   111,108,111,114,86,97,108,117,101,95,6,-80,34,96,
                  <i style="color:gray">[remainder omitted]</i>
&lt;/Property&gt;</pre>
    <p>What are all of these numbers? This is a <i>serialized</i> object.
    The form editor knows nothing about your component, but needs some way
    to save the state of our <code>ColorValue</code> object.  The only
    built-in way Java has to do that is to use serialization to save the
    in-memory representation of your object as an array of bytes.  The form
    editor then translates that array of bytes into a terribly inefficient
    comma-delimited string of numbers.
    <p>There are four big problems with using serialization to write out an
    object into the form file:
    <ol>
        <li>It's inefficent &mdash; it takes up a lot of space in the file,
        and takes longer to read and write</li>
        <li>It's not human-readable &mdash; If a form were corrupted in some
        way, the user doesn't have any chance to figure out what the value
        of this object actually was</li>
        <li>It's fragile &mdash; the data structure depends on the JVM's in-memory
            data structure for the class.  If you add a field or a method
            to <code>ColorValue</code> in the future, the data in all existing
            <code>.form</code> files will be unusable.  That means users will
            lose their components and have to recreate them, or they must never
            edit a form with a <code>Bean1</code> on it again.
        </li>
    </ol>
    There is another way.  Although nobody truly loves writing DOM code, you can
    implement XMLPropertyEditor.  What happens then is:
    <ol>
        <li>When the form is saved, the form editor will make an instance of
            the property editor for the property
        </li>
        <li>The property editor will be passed the XML <code>Document</code> and
        asked to provide a document node that contains data about the component</li>
        <li>The next time the form is opened, the form editor will read the name
            <code>org.netbeans.demo.form.beanlib.editors.ColorValueEditor</code> in
            the XML, make an instance of our editor, and ask it to read the
            XML that was written out and create an instance of <code>ColorValue</code>
            to display in the form editor.</li>
    </ol>
    By using XML instead of serialization, we get to choose what data we store in
    the <code>.form</code> file, how it is stored, and our code is in charge of
    reading it back.  If new properties or fields have been added to <code>ColorValue</code>
    and we are reading an old form, we can just ignore missing values and use some
    reasonable default value.  The result is that our users are protected from
    having corrupted, unopenable forms caused by upgrading to a new version of
    <code>Bean.jar</code>.  To use this approach instead,
    <ol class="instructions">
        <li>Modify the class signature of <code>ColorValueEditor</code> so that
            it implements <code>org.openide.explorer.propertysheet.editors.XMLPropertyEditor</code>.
        </li>
        <li>Implement the methods of <code>XMLPropertyEditor</code> as shown in
            <a href="#listing18">listing 18</a>.</li>
    </ol>
    <h3><a name="listing18">Listing 18:  Implementing XMLPropertyEditor</a></h3>
    <pre>public void readFromXML(Node node) throws IOException {
    NamedNodeMap attrs = node.getAttributes();
    Node red = attrs.getNamedItem("red");
    Node green = attrs.getNamedItem("green");
    Node blue = attrs.getNamedItem("blue");
    if (red != null && green != null && blue != null) {
        value = new ColorValue(
                Integer.parseInt(red.getNodeValue()),
                Integer.parseInt(green.getNodeValue()),
                Integer.parseInt(blue.getNodeValue())
                );
    } else {
        value = new ColorValue(); //use default value
    }
}

public Node storeToXML(Document doc) {
    Element el = doc.createElement("ColorValue");
    if (value != null) {
        el.setAttribute("red", "" + value.getRed());
        el.setAttribute("green", "" + value.getGreen());
        el.setAttribute("blue", "" + value.getBlue());
    }
    return el;
}</pre>

    <p>The above results in:
<pre>&lt;Property name="colorValue" type="bean.ColorValue" editor="org.netbeans.demo.form.beanlib.editors.ColorValueEditor"&gt;
     &lt;ColorValue blue="128" green="235" red="26"/&gt;
&lt;/Property&gt;</pre>

    <h2>Packaging Your Component</h2>
    Once you have your module the way you like it, the next step is to package
    it up so that others can install it.  In NetBeans, this is extremely simple:
    Just right click the module project and choose <b>Create NBM</b>.  This will
    create an NBM (NetBeans Module) file which includes your module and your
    library in a single file any user can install using <b>Tools &gt; Plugins</b>.
    Users of your component do not have to deal with separate JAR and documentation
    downloads, and if they want an updated version of your components, all they
    have to do is install a new NBM to get them.

    <p class="tips">A useful way to deliver components is to set
        up your own <i>update center</i>.  An update center has a list of NBM
        files for download.  Users of NetBeans can just add the URL for your update
        center on the <b>Settings</b> tab in <b>Tools &gt; Plugins</b>.  The IDE
        will automatically check with your server on a regular basis to see if
        there are updates available.
        <p/>
        You can make this process even easier by doing two things:
        <ol>
            <li>Automatically generate the update index using NetBeans:  Just
                create a <b>Module Suite</b> project and add the module to it.
                Right click that project and choose <b>Create NBMs</b>.  Along
                with the NBM file, you get the <code>update.xml</code> file which
                is what the IDE reads to figure out if any updates are there.</li>
            <li>Use <a href="http://hudson.dev.java.net">Hudson</a> to run continuous
                builds of your suite and publish the resulting files.  This way
                you can completely automate publishing new versions of your
                module and libraries.  More information about setting up
                automated builds with Hudson <a href="http://xtest.netbeans.org/XTest_for_Platform.html#Build_application_using_Hudson">can be found here</a></li>
        </ol>
    

    <h2>Wrap Up</h2>
    NetBeans provides a powerful way to deliver Java components to your users,
    including all of the documentation and sources to your users and potential
    users in a single easy-to-use deliverable.  By creating property editors
    that integrate tightly with NetBeans, you can further enhance the ease of
    use of working with your components.

    <!--
    The first is simply an artificial substitute
    for a color, which holds integer red, green and blue values.  The
    second, based on real-world requirements an organization which
    was using NetBeans internally, is a considerably more complicated
    class:  An IdInfo has a string ID, representing one stream of data
    the component will show at runtime.  An IdInfo also has a <i>type</i>
    for the data (Integer, Double or Enum).  When the ID is supplied,
    the component will contact a remote server, and pass it the ID.
    The server will reply with the type of the data.  The component (which
    will represent a measurement of a physical process) will configure itself
    to show data of that type.  The
       -->
   
    </body>
</html>