<!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="../70/nbm-nodesapi2.html">the previous version
                of this document</a>.</p>

        <p><b>Contents</b></p>
        <p><img src="../../images/articles/71/netbeans-stamp.png" 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>

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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


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