<!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>NetBeans Nodes API Tutorial for NetBeans Platform 7.1</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="A walk-through of enhancing Nodes with properties and other decorations."/>
        <!--      Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. -->
        <!--     Use is subject to license terms.-->
    </head>
    <body>
        <h1>NetBeans Nodes API Tutorial</h1>

        <p>This tutorial shows how to make use of some of the features of the Nodes API
            in NetBeans.  It shows how to do the following:</p>
        <ul>
            <li>Decorate Nodes with icons</li>
            <li>Use HTML markup to enhance how Nodes are displayed</li>
            <li>Create properties for display in the property sheet</li>
            <li>Provide Actions from Nodes</li>
        </ul>

        <p>This tutorial is intended as a follow-on to the 
            <a href="nbm-selection-1.html">NetBeans Selection Management Tutorial</a>, which
            covers how <code>Lookup</code> is used in managing selection in the NetBeans 
            windowing system, and its <a href="nbm-selection-2.html">follow-on tutorial</a>
            which demonstrates how to use the Nodes API in managing selection.</p>  

        <p>As its basis, this tutorial uses the source code created in the first tutorial
            and enhanced further in the second.  If you have not yet done these tutorials,
            it is recommended to do them first.</p>

        <p><strong class="notes">Note: </strong>This document uses NetBeans Platform 7.1 and
            NetBeans IDE 7.1. If you
            are using an earlier version, see <a href="71/nbm-nodesapi2.html">the previous version
                of this document</a>.</p>

        <p><b>Contents</b></p>
        <p><img src="../../images/articles/72/netbeans-stamp-71-72.gif" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 7.1" title="Content on this page applies to NetBeans IDE 7.1"/></p>
        <ul class="toc">
            <li><a href="#nodes-background">Creating a Node subclass</a></li>
            <li><a href="#displayname-html">Enhancing Display Names with HTML</a></li>
            <li><a href="#icons">Providing Icons</a></li>
            <li><a href="#actions">Actions and Nodes</a></li>
            <li><a href="#action-presenters">Presenters</a></li>
            <li><a href="#propertysheet">Properties and the Property Sheet</a></li>
            <li><a href="#read-write-properties">Read-Write Properties</a></li>
            <li><a href="#separate-property-groups">Grouping Property Sets</a></li>
            <li><a href="#caveats">General Property Sheet Caveats</a></li>
            <li><a href="#review">Review of Concepts</a></li>
            <li><a href="#next">Next Steps</a></li>
        </ul>

        <p><b>To follow this tutorial, you need the software and resources listed in the following 
                table.</b></p>

        <table>
            <tbody>
                <tr>
                    <th class="tblheader" scope="col">Software or Resource</th>
                    <th class="tblheader" scope="col">Version Required</th>
                </tr>
                <tr>
                    <td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td>
                    <td class="tbltd1">version 7.1 or above</td>
                </tr>
                <tr>
                    <td class="tbltd1"><a href="http://java.sun.com/javase/downloads/index.jsp">Java Developer Kit (JDK)</a></td>
                    <td class="tbltd1">version 6 or above</td>
                </tr>
            </tbody>
        </table>

        <h2><a name="nodes-background"></a>Creating a Node subclass</h2>
        <p>As mentioned in the <a href="nbm-selection-2.html">previous tutorial</a>,
            Nodes are <i>presentation objects</i>.  That means that they are not a data
            model themselves&#8212;rather, they are a presentation layer for an 
            <i>underlying data model</i>.  In the Projects or Files windows in the NetBeans 
            IDE, you can see <code>Node</code>s used in a case where the underlying data model is 
            files on disk.  In the Services window in the IDE, you can see them used in a case
            where the underlying objects are configurable aspects of NetBeans runtime 
            environment, such as available application servers and databases.</p>
        <p>
            As a presentation layer, <code>Node</code>s add human-friendly attributes to the
            objects they model.  The essential ones are:</p>
        <ul>
            <li><b>Display Name</b>&#8212;a human readable, user-friendly display name</li>
            <li><b>Description</b>&#8212;a human readable, user-friendly description, often shown as a tooltip</li>
            <li><b>Icon</b>&#8212;some glyph that graphically indicates the type of object shown and possibly
                its state</li>
            <li><b>Actions</b>&#8212;actions that appear on the context menu when the node is
                right-clicked, which can be invoked by the user</li>
        </ul>
        <p>In the preceding tutorial, you used your <code>EventChildFactory</code> class
            to create <code>Node</code>s, by calling</p>
        <pre class="examplecode">
new AbstractNode(Children.create(new EventChildFactory(), true), Lookups.singleton(key));</pre>
        <p>and then calling <code>setDisplayName(key.toString())</code> to provide a basic
            display name.  There is much more that can be done to make your <code>Node</code>s more
            user-friendly.  First you will need to create a <code>Node</code> subclass to
            work with:</p>

        <div class="indent">

            <ol>
                <li>In the My Editor project, right click the package <code>org.myorg.myeditor</code>
                    and choose New &gt; Java Class.</li>
                <li>When the wizard opens, name the class &quot;EventNode&quot; and press Enter
                    or click Finish.</li>
                <li>Change the signature and constructors of the class as follows:
                    <pre class="examplecode">
public class EventNode extends AbstractNode {

    public EventNode(Event obj) {
        super (Children.create(new EventChildFactory(), true), Lookups.singleton(obj));
        setDisplayName ("Event " + obj.getIndex());
    }
    
    public EventNode() {
        super (Children.create(new EventChildFactory(), true));
        setDisplayName ("Root");
    }

    ....
    ....
    ....

                    </pre>
                </li>
                <li>Open <code>MyEditor</code> from the same package, in the code editor.</li>
                <li>Replace these lines in the constructor:
                    <pre class="examplecode">
mgr.setRootContext(new AbstractNode(new EventChildFactory()));
setDisplayName ("My Editor");</pre>
                    with this single line of code:
                    <pre class="examplecode">
mgr.setRootContext(new EventNode());</pre>
                </li>
                <li>Now you will make a similar change to the Children object.  Open 
                    the <code>EventChildFactory</code> class in the editor, and change its
                    <code>createNodes</code> method as follows:
                    <pre class="examplecode">
@Override
protected Node createNodeForKey(Event key) {
    return new EventNode(key);
}</pre>
                </li>

            </ol>

        </div>

        <h2><a name="displayname-html"></a>Enhancing Display Names with HTML</h2>

        <p>The code is now runnable, but so far all you've done is moved logic around.  It 
            will do exactly what it did before.  The only (non-user-visible) difference you 
            now are using a Node subclass instead of just using AbstractNode.</p>
        <p>
            The first thing you will do is provide an enhanced display name.  The Nodes and
            Explorer APIs support a limited subset of HTML which you can use to enhance how
            the labels for <code>Node</code>s are shown in Explorer UI components.  The following
            tags are supported:</p>
        <ul>
            <li>font color&#8212;font size and face settings are not supported, but color is,
                using standard html syntax</li>
            <li>font style tags&#8212;b,i,u and s tags&#8212;bold, italic, underline, strikethrough</li>
            <li>A limited subset of SGML entities: &amp;quot;, &amp;lt;, &amp;amp;, &amp;lsquo;,
                &amp;rsquo;, &amp;ldquo;, &amp;rdquo;, &amp;ndash;,
                &amp;mdash;, &amp;ne;, &amp;le;, &amp;ge;,
                &amp;copy;, &amp;reg;, &amp;trade;, and &amp;nbsp;
            </li>
        </ul>

        <p>Since
            there is no terribly exciting data available from your <code>Event</code>, which
            only has an integer and a creation date, you'll extend this artificial example,
            and decide that odd numbered <code>Events</code> should appear with blue text.</p>

        <div class="indent">

            <ol>
                <li>Add the following method to <code>EventNode</code>:
                    <pre class="examplecode">
@Override
public String getHtmlDisplayName() {
    Event obj = getLookup().lookup (Event.class);
    if (obj!=null && obj.getIndex() % 2 != 0) {
        return "&lt;font color='0000FF'&gt;Event " + obj.getIndex() + "&lt;/font&gt;";
    } else {
        return null;
    }
}</pre></li>

                <li><p>What the above code accomplishes is this&#8212;when painting, the Explorer component showing
                        the nodes calls <code>getHtmlDisplayName()</code> first.  If it gets a non-null
                        value back, then it will use the HTML string it received and a fast, lightweight HTML
                        renderer to render it.  If it is null, then it will fall back to whatever is 
                        returned by <code>getDisplayName()</code>.  So this way, any <code>EventNode</code>
                        whose <code>Event</code> has an index not divisible by 2 will have a non-null
                        HTML display name.</p>
                    <p>Run the Event Manager again and you should see the following:</p>

                    <p>
                        <img style="border:1px solid black" alt="" src="../../images/tutorials/nodes-2/71/technicolor-nodes-71.png"/></p>

                </li>

            </ol>

        </div>

        <p>There are two reasons for <code>getDisplayName()</code> and 
            <code>getHtmlDisplayName()</code> being
            separate methods&#8212;first, it is an optimization;  second, as you will see later,
            it makes it possible to compose HTML strings together, without needing to strip
            &lt;html&gt; marker tags.</p>

        <p>You can enhance this further&#8212;in the previous tutorial, the date was included
            in the HTML string, and you have removed it here.  So let's make your HTML string
            a little more complex, and provide HTML display names for all of your nodes.</p>

        <div class="indent">

            <ol>
                <li>Modify the <code>getHtmlDisplayName()</code> method as follows:
                    <pre class="examplecode">
@Override
public String getHtmlDisplayName() {
    Event obj = getLookup().lookup (Event.class);
    if (obj != null) {
        return "&lt;font color='#0000FF'&gt;Event " + obj.getIndex() + "&lt;/font&gt;" +
                "&lt;font color='AAAAAA'&gt;&lt;i&gt;" + obj.getDate() + "&lt;/i&gt;&lt;/font&gt;";
    } else {
        return null;
    }
}</pre>
                </li>
                <li><p>Run the Event Manager again and now you should see the following:</p>

                    <p><img style="border:1px solid black" alt="" src="../../images/tutorials/nodes-2/71/technicolor-nodes-2-71.png"/></p></li>
            </ol>

        </div>

        <p>One minor thing you can do to improve appearance here:  You are currently using
            hard-coded colors in your HTML.  Yet NetBeans can run under various look and 
            feels, and there's no guarantee that your hard-coded color will not be the same as
            or very close to the background color of the tree or other UI component your Node appears in.</p>  

        <p>The NetBeans HTML renderer provides a minor extension to the HTML spec
            which makes it possible to look up colors by passing UIManager keys.  
            The look and feel Swing is using provides a UIManager, 
            which manages a name-value map of the colors and fonts a given 
            look and feel uses.  Most (but not all) look and feels find the colors to 
            use for different GUI elements by calling <code>UIManager.getColor(String)</code>,
            where the string key is some agreed-upon value.  So by using values from 
            UIManager, you can guarantee that
            you will always be producing readable text.  The two keys you will use are 
            &quot;textText&quot;, which returns the default color for text (usually black
            unless using a look and feel with a dark-background theme), and 
            &quot;controlShadow&quot; which should give us a color that contrasts, but not
            too much, with the default control background color.</p>

        <div class="indent">

            <ol>
                <li>Modify the <code>getHtmlDisplayName()</code> method as follows:
                    <pre class="examplecode">
@Override
public String getHtmlDisplayName() {
    Event obj = getLookup().lookup (Event.class);
    if (obj != null) {
        return "&lt;font color='!textText'&gt;Event " + obj.getIndex() + "&lt;/font&gt;" +
                "&lt;font color='!controlShadow'&gt;&lt;i&gt;" + obj.getDate() + "&lt;/i&gt;&lt;/font&gt;";
    } else {
        return null;
    }
}</pre>
                </li>
                <li><p>Run the Event Manager again and now you should see the following:</p>

                    <p><img style="border:1px solid black" alt="" src="../../images/tutorials/nodes-2/71/technicolor-nodes-3-71.png"/></p></li>

            </ol>

        </div>

        <p>You'll note above that you got rid of your blue color and switched to plain old
            black.  Using the value of <code>UIManager.getColor("textText")</code> guarantees us
            text that will always be readable under any look and feel, which is valuable;
            also, color should be used sparingly in user interfaces, to avoid the
            <a href="http://www.catb.org/jargon/html/A/angry-fruit-salad.html">angry fruit salad</a>
            effect.  If you really want to use wilder colors in your UI, the best bet is to
            either find a UIManager key/value pair that consistently gets what you want, or
            create a <a href="http://wiki.netbeans.org/wiki/view/DevFaqModulesGeneral">ModuleInstall</a>
            class and 
            <a target="other" href="http://core.netbeans.org/source/browse/*checkout*/core/swing/plaf/src/org/netbeans/swing/plaf/util/RelativeColor.java">
                <i>derive the color</i></a> <i>from a color you can get from UIManager</i>, or if
            you are sure you know the color theme of the look and feel, hard-code it on a 
            per-look and feel basis (<code>if ("aqua".equals(UIManager.getLookAndFeel().getID())...</code>).</p>

        <h2><a name="icons"></a>Providing Icons</h2>
        <p>Icons, used judiciously, also enhance user interfaces.  So providing 16x16 pixel
            icon is another way to improve the appearance of your UI.  One caveat of using 
            icons is, do not attempt to convey too much information via an icon&#8212;there are 
            not a lot of pixels there to work with.  A second caveat that applies to both
            icons and display names is, <i>never use only color to distinguish a node</i>&#8212;
            there are many people in the world who are colorblind.</p>

        <p>Providing an icon is quite simple&#8212;you just load an image and set it.  You 
            will need to have a GIF or PNG file to use. If you do not have one easily
            available, here is one you can use:</p>

        <p><img src="../../images/tutorials/nodes-2/icon.png" /></p>

        <div class="indent">

            <ol>
                <li>Copy the image linked above, or another 16x16 PNG or GIF, into the same package as
                    the <code>MyEditor</code> class.
                </li>
                <li>
                    Add the following method to the <code>EventNode</code> class:
                    <pre class="examplecode">
@Override
public Image getIcon (int type) {
    return ImageUtilities.loadImage ("org/myorg/myeditor/icon.png");
}</pre>
                    Note that it is possible to have different icon sizes and styles&#8212;the possible
                    int values passed to <code>getIcon()</code> are constants on <code>java.beans.BeanInfo</code>,
                    such as <code>BeanInfo.ICON_COLOR_16x16</code>.  Also, while you can use the
                    standard JDK <code>ImageIO.read()</code> to load your images, <code>ImageUtilities.loadImage()</code>
                    is more optimized, has better caching behavior, and supports branding of images.
                </li>
                <li><p>If you run the code now, you will notice one thing&#8212;the icon is used for
                        some nodes but not others!  The reason for this is that it is common to use a 
                        different icon for an unexpanded versus an expanded <code>Node</code>.  All you
                        need to do to fix this is to override another method.</p>

                    <p>Add the following additional method to the <code>EventNode</code>:</p>
                    <pre class="examplecode">
@Override
public Image getOpenedIcon(int i) {
    return getIcon (i);
}</pre>
                </li>


                <li><p>Now if you run the Event Manager, all of the Nodes will have the correct icon, as shown below:
                    </p>
                    <p><img style="border:1px solid black" alt="" src="../../images/tutorials/nodes-2/71/technicolor-nodes-4-71.png"/></p></li>

            </ol>

        </div>

        <h2><a name="actions"></a>Actions and Nodes</h2>
        <p>The next aspect of <code>Node</code>s you will treat is <i>Actions</i>.  A
            <code>Node</code> has a popup menu which can contain actions that the user
            can invoke against that <code>Node</code>.  Any subclass of <code>javax.swing.Action</code> can
            be provided by a <code>Node</code>, and will show up in its popup menu.  Additionally, there
            is the concept of <i>presenters</i>, which you will cover later.</p>
        <p>
            First, let's create a simple action for your nodes to provide:</p>

        <div class="indent">

            <ol>
                <li>Override the <code>getActions()</code> method of <code>EventNode</code> as
                    follows:
                    <pre class="examplecode">
@Override
public Action[] getActions (boolean popup) {
    return new Action[] { new MyAction() };
}</pre>
                </li>
                <li>Now, create the <code>MyAction</code> class as an inner class of <code>EventNode</code>:
                    <pre class="examplecode">
private class MyAction extends AbstractAction {

    public MyAction () {
        putValue (NAME, &quot;Do Something&quot;);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Event obj = getLookup().lookup(Event.class);
        JOptionPane.showMessageDialog(null, &quot;Hello from &quot; + obj);
    }

} </pre> </li>

                <li><p>Run the Event Manager again and notice that when you right-click
                        on a node, a menu item is shown:</p>
                    <p><img style="border:1px solid black" alt="" src="../../images/tutorials/nodes-2/71/technicolor-nodes-5-71.png"/></p></li>
                <p>When you select the menu item, the action is invoked:</p>
                <p><img alt="" src="../../images/tutorials/nodes-2/71/technicolor-nodes-6-71.png"/></p></li>
            </ol>

        </div>

        <h2><a name="action-presenters"></a>Presenters</h2>
        <p>Of course, sometimes you will want to provide a submenu or checkbox menu item or
            some other component, other than a JMenuItem, to display in the popup menu.  This
            is quite easy:</p>

        <div class="indent">

            <ol>
                <li>Add to the signature of <code>MyAction</code> that it implements <code>Presenter.Popup</code>:
                    <pre class="examplecode">private class MyAction extends AbstractAction implements Presenter.Popup {</pre>
                </li>

                <li>Press Ctrl-Shift-I to fix imports.</li>

                <li>Position the caret in the class signature line of <code>MyAction</code> and 
                    press Alt-Enter when the lightbulb glyph appears in the margin, and accept 
                    the hint &quot;Implement All Abstract Methods&quot;.</li>

                <li>Implement the newly created method <code>getPopupPresenter()</code> as follows:
                    <pre class="examplecode">
@Override
public JMenuItem getPopupPresenter() {
    JMenu result = new JMenu("Submenu");  //remember JMenu is a subclass of JMenuItem
    result.add (new JMenuItem(this));
    result.add (new JMenuItem(this));
    return result;
}</pre></li>

                <li><p>Run the Event Manager again and notice that you now have the following:</p>
                    <p> <img style="border:1px solid black" alt="" src="../../images/tutorials/nodes-2/71/action-with-presenter-71.png"/>
                    </p>
                    <p>The result is not too exciting&#8212;you now have a submenu called "Submenu" with two 
                        identical menu items.  But again, you should get the idea of what is possible
                        here&#8212;if you want to return a <code>JCheckBoxMenuItem</code> or some other kind
                        of menu item, it is possible to do that.</p>
                </li>

            </ol>

        </div>

        <h2><a name="propertysheet"></a>Properties and the Property Sheet</h2>

        <p>The last subject you'll cover in this tutorial is properties.  You are probably aware that NetBeans
            IDE contains a &quot;property sheet&quot; which can display the 
            &quot;properties&quot; of a <code>Node</code>.  What exactly &quot;properties&quot; means
            depends on how the <code>Node</code> is implemented.  Properties are essentially
            name-value pairs which have a Java type, which are grouped in sets and shown in
            the property sheet&#8212;where writable properties can be edited via their <i>property editors</i>
            (see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/beans/PropertyEditor.html"><code>java.beans.PropertyEditor</code></a>
            for general information about property editors).</p>

        <p>So, built into <code>Node</code>s from the ground up is the idea that a Node may
            have properties that can be viewed and, optionally, edited on a property sheet.
            Adding support for this is quite easy.  There is a convenience class in the 
            Nodes API, <code>Sheet</code>, which represents the entire set of properties for
            a Node.  To it you may add instances of <code>Sheet.Set</code>, which represent
            &quot;property sets&quot;, which appear in the property sheet as groups of 
            properties.</p>

        <div class="indent">

            <ol>
                <li>Override <code>EventNode.createSheet()</code> as follows:

                    <pre class="examplecode">@Override
protected Sheet createSheet() {

    Sheet sheet = Sheet.createDefault();
    Sheet.Set set = Sheet.createPropertiesSet();
    Event obj = getLookup().lookup(Event.class);

    try {

        Property indexProp = new PropertySupport.Reflection(obj, Integer.class, "getIndex", null);
        Property dateProp = new PropertySupport.Reflection(obj, Date.class, "getDate", null);

        indexProp.setName("index");
        dateProp.setName("date");

        set.put(indexProp);
        set.put(dateProp);

    } catch (NoSuchMethodException ex) {
        ErrorManager.getDefault();
    }

    sheet.put(set);
    return sheet;

}</pre>
                </li>

                <li>Press Ctrl-Shift-I to Fix Imports.</li>
                <li>Right click the EventManager and choose Run and then, once it is started up,
                    use Window &gt; Open Editor to show your editor.</li>
                <li>Select Window &gt; Properties to show the NetBeans property sheet.</li>
                <li><p>Click in your editor window and move the selection between different
                        nodes, and notice the property sheet updating, just as your <code>MyViewer</code>
                        component does, as shown below:</p>

                    <p><img alt="" src="../../images/tutorials/nodes-2/71/property-sheet-71.png"/></p>

                </li>

            </ol>

        </div>

        <p>The above code makes use of a very convenient class:  <code>PropertySupport.Reflection</code>,
            which may simply be passed an object, a type, and getter and setter method names, and
            it will create a Property object that can read (and optionally write) that property
            of the object in question.  So you use <code>PropertySupport.Reflection</code> a 
            simple way to wire one <code>Property</code>
            object up to the <code>getIndex()</code> method of <code>Event</code>.</p>

        <p>If you want <code>Property</code> objects for nearly all of the getters/setters
            on an underlying model object, you may want to use or subclass <code>BeanNode</code>,
            which is a full implementation of <code>Node</code> that can be given a random object
            and will try to create all the necessary properties for it (and listen for changes)
            via reflection (how exactly they are presented can be controlled by creating a 
            <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/beans/BeanInfo.html"><code>BeanInfo</code></a>
            for the class of the object to be represented by the node).</p>

        <blockquote>
            <p><font color="red"><b>Caveat:</b> Setting the <code>name</code> of your properties is
                    very important.  Property objects test their equality based on names.  If you
                    are adding some properties to a <code>Sheet.Set</code> and they seem to be
                    disappearing, very probably their name is not set&#8212;so putting one property
                    in a <code>HashSet</code> with the same (empty) name as another is causing
                    later added ones to displace earlier added ones.</font></p>
        </blockquote>

        <h2><a name="read-write-properties"></a>Read-Write Properties</h2>

        <p>To play with this concept further, what you really need is a read/write property.
            So the next step is to add some additional support to <code>Event</code> to 
            make the <code>Date</code> property settable.</p>

        <div class="indent">

            <ol>
                <li>Open <code>org.myorg.myapi.Event</code> in the code editor.</li>
                <li>Remove the <code>final</code> keyword from the line declaring the <code>date</code> field</li>
                <li>Add the following setter and property change support methods to <code>Event</code>:
                    <pre class="examplecode">
private List listeners = Collections.synchronizedList(new LinkedList());

public void addPropertyChangeListener (PropertyChangeListener pcl) {
    listeners.add (pcl);
}

public void removePropertyChangeListener (PropertyChangeListener pcl) {
    listeners.remove (pcl);
}

private void fire (String propertyName, Object old, Object nue) {
    //Passing 0 below on purpose, so you only synchronize for one atomic call:
    PropertyChangeListener[] pcls = (PropertyChangeListener[]) listeners.toArray(new PropertyChangeListener[0]);
    for (int i = 0; i < pcls.length; i++) {
        pcls[i].propertyChange(new PropertyChangeEvent (this, propertyName, old, nue));
    }
}</pre>
                </li>
                <li>Now, within the <tt>Event</tt>, call the <tt>fire</tt> method above:

                    <pre>public void setDate(Date d) {
    Date oldDate = date;
    date = d;
    fire("date", oldDate, date);
 }</pre>    </li>

                <li>In <code>EventNode.createSheet()</code>, change the way <code>dateProp</code> is 
                    declared, so that it will be writable as well as readable:
                    <pre class="examplecode">
Property dateProp = new PropertySupport.Reflection(obj, Date.class, &quot;date&quot;);</pre>
                    Now, rather than specifying explicit getters and setters, you are just providing
                    the property name, and <code>PropertySupport.Reflection</code> will find the
                    getter and setter methods for us (and in fact it will also find the 
                    <code>addPropertyChangeListener()</code> method automatically).
                </li>
                <li><p>Re-run the module Event Manager, and notice that you can now select an instance of
                        <code>EventNode</code> in <code>MyEditor</code> and actually edit the date value, as shown
                        below:</p>
                    <p> <img style="border:1px solid black" alt="" src="../../images/tutorials/nodes-2/71/action-with-presenter-71-2.png"/>
                    </p>

                    <p><b>Note:</b> The result is persisted when you restart the IDE.</p></li>

            </ol>

        </div>

        <p>However, there is still one bug in this code&#8212;when you change the Date property,
            you should also update the display name of your node.  So you will make one more
            change to <code>EventNode</code> and have it listen for property changes on 
            <code>Event</code>.</p>

        <div class="indent">

            <ol>
                <li>Modify the signature of <code>EventNode</code> so that it implements 
                    <code>java.beans.PropertyChangeListener</code>:
                    <pre class="examplecode">
public class EventNode extends AbstractNode implements PropertyChangeListener {</pre>
                </li>
                <li>Press Ctrl-Shift-I to Fix Imports.</li>
                <li>Placing the caret in the signature line, accept the hint &quot;Implement
                    All Abstract Methods&quot;.</li>
                <li>Add the following line to the constructor which takes an argument of 
                    <code>Event</code>:
                    <pre class="examplecode">obj.addPropertyChangeListener(WeakListeners.propertyChange(this, obj));</pre>
                    Note that here you are using a utility method on <code>org.openide.util.WeakListeners</code>.
                    This is a technique for avoiding memory leaks&#8212;an <code>Event</code> will only
                    weakly reference its <code>EventNode</code>, so if the <code>Node</code>'s parent
                    is collapsed, the <code>Node</code> can be garbage collected.  If the <code>Node</code>
                    were still referenced in the list of listeners owned by <code>Event</code>,
                    it would be a memory leak.
                    In your case, the <code>Node</code> actually owns the <code>Event</code>,
                    so this is not a terrible situation&#8212;but in real world programming, objects in
                    a data model (such as files on disk) may be much longer-lived than <code>Node</code>s
                    displayed to the user.  Whenever you add a listener to an object which you never
                    explicitly remove, it is preferable to use <code>WeakListeners</code>&#8212;otherwise
                    you may create memory leaks which will be quite a headache later.  If you instantiate
                    a separate listener class, though, be sure to keep a strong reference to it from
                    the code that attaches it&#8212;otherwise it will be garbage collected almost as soon
                    as it is added.
                </li>
                <li>Finally, implement the <code>propertyChange()</code> method:
                    <pre class="examplecode">
public void propertyChange(PropertyChangeEvent evt) {
    if ("date".equals(evt.getPropertyName())) {
        this.fireDisplayNameChange(null, getDisplayName());
    }
}</pre>
                </li>
                <li><p>Run the module Event Manager again, select a <code>EventNode</code> in the
                        <code>MyEditor</code> window and change its <code>Date</code> property&#8212;notice
                        that the display name of the <code>Node</code> is now updated 
                        correctly, as shown below, where the year 2009 and is now reflected both
                        on the node and in the property sheet:</p>
                    <p> <img style="border:1px solid black" alt="" src="../../images/tutorials/nodes-2/71/action-with-presenter-71-3.png"/>
                    </p>

                </li>

            </ol>

        </div>

        <h2><a name="separate-property-groups"></a>Grouping Property Sets</h2>
        <p>You may have noticed when running Matisse, NetBeans IDE's 
            form editor, that there is a set
            of buttons at the top of the property sheet, for switching between groups of
            property sets.</p>

        <p>Generally this is only advisable if you have a really large number of 
            properties, and generally it's not advisable for ease-of-use <i>to</i> have a
            really large number of properties.  Nonetheless, if you feel you need to split
            out your sets of properties into groups, this is easy to accomplish.</p>

        <p><code>Property</code> has the methods <code>getValue()</code> and 
            <code>setValue()</code>, as does <code>PropertySet</code> (both of them 
            inherit this from 
            <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/beans/FeatureDescriptor.html"><code>java.beans.FeatureDescriptor</code></a>).
            These methods can be used in certain cases, for passing ad-hoc &quot;hints&quot;
            between a given <code>Property</code> or <code>PropertySet</code> 
            and the property sheet or certain kinds of property 
            editor (for example, passing a default filechooser directory to an editor for
            <code>java.io.File</code>).  
            And that is the technique by which you can specify a group name (to be
            displayed on a button) for one or more <code>PropertySet</code>s.  In real world
            coding, this should be a localized string, not a hard-coded string as below:</p>

        <div class="indent">

            <ol>
                <li>Open <code>EventNode</code> in the code editor</li>
                <li>Modify the method <code>createSheet()</code> as follows (modified and 
                    added lines are highlighted):
                    <pre class="examplecode">
    @Override
    protected Sheet createSheet() {
        
        Sheet sheet = Sheet.createDefault();
        Sheet.Set set = sheet.createPropertiesSet();
        <b>Sheet.Set set2 = sheet.createPropertiesSet();
        set2.setDisplayName("Other");
        set2.setName("other");</b>
        Event obj = getLookup().lookup (Event.class);

        try {
        
            Property indexProp = new PropertySupport.Reflection(obj, Integer.class, "getIndex", null);
            Property dateProp = new PropertySupport.Reflection(obj, Date.class, "date");
            
            indexProp.setName("index");
            dateProp.setName ("date");
            set.put (indexProp);
            
            <b>set2.put (dateProp);
            set2.setValue("tabName", "Other Tab");</b>
            
        } catch (NoSuchMethodException ex) {
            ErrorManager.getDefault();
        }
        
        sheet.put(set);
        <b>sheet.put(set2);</b>
        return sheet;
        
    }</pre>
                </li>
                <li><p>Run the Event Manager again, and notice that there are now buttons at the top
                        of the property sheet, and there is one property under each, as seen here:</p>

                    <p> <img style="border:1px solid black" alt="" src="../../images/tutorials/nodes-2/71/other-tab-71.png"/>
                    </p>

                </li>

            </ol>

        </div>

        <h2><a name="caveats"></a>General Property Sheet Caveats</h2>
        <p>If you used NetBeans 3.6 or earlier, you may
            notice that older versions of NetBeans employed the property sheet very heavily
            as a core element of the UI, whereas it's not so prevalent today.  The reason is
            simple:  <i>property sheet based UIs are not terribly user-friendly</i>.  That
            doesn't mean don't use the property sheet, but use it judiciously.  If you have
            the option of providing a customizer with a nice GUI, do so&#8212;your users will 
            thank you.  </p>
        <p>And if you have an enormous number of properties on one object, try
            to find some overall settings that encapsulate the most probable combinations of
            settings.  For example, think of what the settings for a tool for managing imports on a Java 
            class can be&#8212;you can provide integers for setting the threshold number of usages of a package 
            required for wildcard imports, the threshold number of uses of a fully qualified
            class name required before importing it at all, and lots of other numbers ad 
            nauseum.  Or you can ask yourself the question, <i>what is the user trying to 
                do?</i>.  In this case, it's either going to be getting rid of import statements
            or getting rid of fully qualified names.  So probably settings
            of <i>low noise, medium noise</i> and <i>high noise</i> where &quot;noise&quot; 
            refers to the amount of fully qualified class/package names in the 
            edited source file would do just as well and be much 
            easier to use.  Where you can make life simpler for the user, do so.</p>

        <h2><a name="review"></a>Review of Concepts</h2>
        This tutorial has sought to get across the following ideas:
        <p></p>
        <ul>
            <li>Nodes are a presentation layer</li>
            <li>The display names of Nodes can be customized using a limited subset of HTML</li>
            <li>Nodes have icons, and you can provide custom icons for nodes you create</li>
            <li>Nodes have Actions;  an Action which implements Presenter.Popup can provide
                its own component to display in a popup menu;  the same is true for main
                menu items using Presenter.Menu, and toolbar items using Presenter.Toolbar</li>
            <li>Nodes have properties, which can be displayed on the property sheet</li>
        </ul>

        <div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&amp;subject=Feedback:%20Nodes%20API%207.1%20Module%20Tutoria">Send Us Your Feedback</a></div>

        <h2><a name="next"></a>Next Steps</h2>
        <p>You've now begun to delve into how to get more out of the property sheet in
            NetBeans.  In the <a href="nbm-property-editors.html">next tutorial</a>, you will
            cover how to write custom editors and provide a custom inline editor for use
            in the property sheet.</p>

    </body>
</html>
