<!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) 2009, 2010, Oracle and/or its affiliates. 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.
                                                <div class="indent">
                                                    <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>
                                                </div>
                                                <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).
                                                <div class="indent">

                                                    <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>
                                                    <div>
                                                        <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:
                                                        <div class="indent">
                                                            <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>
                                                        </div>
                                                        <p>NetBeans comes with built-in support for creating modules, so setting
                                                            up a new module project is quite simple:</p>
                                                        <div class="indent">
                                                            <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>
                                                        </div>
                                                        <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>
                                                            <p>Causing a module to request that the IDE restart itself before it is
                                                                installed is as simple as checking a checkbox:</p>
                                                            <div class="indent">

                                                                <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>
                                                            </div>
                                                            <h2><a name="tweakBuildScript">Modifying the Plug-In's Build Script</a></h2>
                                                            <p>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:</p>
                                                            <div class="indent">

                                                                <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></div>
                                                            <p>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).</p>
                                                            <div class="indent">
                                                                <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>
                                                            </div>
                                                            <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>
                                                                    <p>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:</p>
                                                                    <div class="indent">
                                                                        <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>
                                                                    </div>
                                                                    <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>
                                                                    <p>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>.</p>
                                                                    <div class="indent">
                                                                        <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>
                                                                    </div>
                                                                    <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>
                                                                    <p>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:</p>
                                                                    <div class="indent">
                                                                        <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>
                                                                    </div>
                                                                    <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>

                                                                    <p>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.</p>

                                                                    <h2>Including <code>Bean.jar</code> on the Module's Class Path</h2>
                                                                    <p>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>

                                                                    <p class="tips">
                                                                        <p>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:</p>
                                                                        <div class="indent">
                                                                            <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>
                                                                        </div>
                                                                        <p>To add <code>Bean.jar</code> to the classpath of <i>classes in your module</i>,
                                                                            do the following:</p>
                                                                        <div class="indent">
                                                                            <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>
                                                                        </div>
                                                                        <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>
                                                                        <p>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.</p>
                                                                        <div class="indent">
                                                                            <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>
                                                                        </div>
                                                                        <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>
                                                                        <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>

                                                                        <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/>
                                                                            <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:</p>
                                                                            <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>
                                                                            <p>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.</p>
                                                                            <div class="indent">

                                                                                <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>
                                                                            </div>
                                                                            <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>
                                                                            <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/>
                                                                                <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:</p>
                                                                                <div class="indent">
                                                                                    <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>
                                                                                </div>
                                                                                <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>
                                                                                    <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.</p>
                                                                                </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>
                                                                                <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:</p>
                                                                                <div class="indent">
                                                                                    <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>
                                                                                </div>
                                                                                <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>
                                                                                <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:</p>
                                                                                <div class="indent">
                                                                                    <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>
                                                                                </div>
                                                                                <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>.</p>


                                                                                <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>
                                                                                <p>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/>
                                                                                <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.</p>

                                                                                <h2>Adding A Custom Editor</h2>
                                                                                <p>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:</p>
                                                                                <div class="indent">
                                                                                    <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>
                                                                                </div>
                                                                                <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>

                                                                                <p>Now we just need to modify <code>ColorValueEditor</code> to actually
                                                                                    create a <code>ColorValueCustomEditor</code>.  To do that:</p>
                                                                                <div class="indent">
                                                                                    <ol class="instructions">
                                                                                        <li>Update the <code>supportsCustomEditor()</code> and <code>getCustomEditor()</code>
                                                                                            to look like <a href="#listing17">listing 17</a></li>
                                                                                    </ol>
                                                                                </div>
                                                                                <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>

                                                                                <p>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.</p>

                                                                                <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>
                                                                                <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:</p>
                                                                                <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>
                                                                                <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>
                                                                                <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>
                                                                                <p>There are four big problems with using serialization to write out an
                                                                                    object into the form file:</p>
                                                                                <div class="indent">

                                                                                    <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>
                                                                                </div>
                                                                                <p>There is another way.  Although nobody truly loves writing DOM code, you can
                                                                                    implement XMLPropertyEditor.  What happens then is:</p>
                                                                                <div class="indent">
                                                                                    <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>
                                                                                </div>
                                                                                <p>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,</p>
                                                                                <div class="indent">

                                                                                    <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>
                                                                                </div>
                                                                                <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>

                                                                                <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>
                                                                                <p/>
                                                                                <p>You can make this process even easier by doing two things:</p>
                                                                                <div class="indent">
                                                                                    <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>
                                                                                </div>

                                                                                <h2>Wrap Up</h2>
                                                                                <p>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.</p>

                                                                                <!--
                                                                                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>