<!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>Nodes API Tutorial for the NetBeans Platform</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, 2011, 2012, 2013, 2014 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 8.0 and
            NetBeans IDE 8.0. If you
            are using an earlier version, see <a href="74/nbm-nodesapi2.html">the previous version
                of this document</a>.</p>

        <p><b>Contents</b></p>
        <p><img src="../images/articles/80/netbeans-stamp.png" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 8.0" title="Content on this page applies to NetBeans IDE 8.0"/></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 8.0 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 7 or above</td>
                </tr>
            </tbody>
        </table>

        <p class="tips">For troubleshooting purposes, you are welcome to download the <a href="http://java.net/projects/nb-api-samples/sources/api-samples/show/versions/8.0/tutorials/selection-management/3-of-4/EventManager">completed tutorial source code</a>.</p>

        <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, as instructed below.</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. 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">package org.myorg.myeditor;

import org.myorg.myapi.Event;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.util.lookup.Lookups;

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. 
                    Remove these lines in the constructor:
                    <pre class="examplecode">
mgr.setRootContext(new AbstractNode(new EventChildFactory()));
setDisplayName ("My Editor");</pre>
                    Instead of the above, add this single line of code:
                    <pre class="examplecode">
mgr.setRootContext(new EventNode());</pre>
                </li>
                <li>Now make a similar change to the <tt>EventChildFactory</tt> class.  Open 
                    it in the editor, and change its
                    <code>createNodeForKey</code> method as follows:
                    <pre class="examplecode">
@Override
protected Node createNodeForKey(Event key) {
    return new EventNode(key);
}</pre>
                </li>

            </ol>

        </div>

        <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 <tt>Node</tt> subclass instead of just using <tt>AbstractNode</tt>.</p>

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

        <p>
            The first enhancement you will provide is an enhanced display name.  The Nodes API
            supports 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. Run the Event Manager again and you should see the following:</p>

                    <p>
                        <img alt="" src="../images/tutorials/nodes-2/73/html-display-1.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);
    <b>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;";
    }</b> else {
        return null;
    }
}</pre>
                </li>
                <li><p>Run the Event Manager again and now you should see the following:</p>

                    <p><img alt="" src="../images/tutorials/nodes-2/73/html-display-2.png"/></p>
            </ol>

        </div>

        <p>One minor thing you can do to improve appearance here&#8212;you are currently using
            hard-coded colors in your HTML.  Yet the NetBeans Platform 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 alt="" src="../images/tutorials/nodes-2/73/html-display-3.png"/></p>

            </ol>

        </div>

        <p class="notes"><b>Note:</b> 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>
                    <p class="notes"><b>Note:</b> 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.</p>
                </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!</p>
                    <p><img alt="" src="../images/tutorials/nodes-2/73/icon-display-1.png"/></p>
                    <p>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. Add the following additional method to the <code>EventNode</code>:</p>
                    <pre class="examplecode">
@Override
public Image getOpenedIcon(int i) {
    return getIcon (i);
}</pre>

                    </p>
                    <p>Now if you run the Event Manager, all of the Nodes will have the correct icon, as shown below:
                    </p>
                    <p><img alt="" src="../images/tutorials/nodes-2/73/icon-display-2.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 alt="" src="../images/tutorials/nodes-2/73/action-display-1.png"/></p></li>
                <p>When you select the menu item, the action is invoked:</p>
                <p><img alt="" src="../images/tutorials/nodes-2/73/action-display-2.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><p>Add to the signature of <code>MyAction</code> that it implements <code>Presenter.Popup</code>:</p>
                    <pre class="examplecode">private class MyAction extends AbstractAction <b>implements Presenter.Popup</b> {</pre>

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

                <li><p>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;. 
                        Implement the newly created method <code>getPopupPresenter()</code> as follows:</p>
                    <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 alt="" src="../images/tutorials/nodes-2/73/action-display-3.png"/></p>
                </li>

            </ol>

        </div>

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

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

                <p>Press Ctrl-Shift-I to Fix Imports.</p></li>
                <li>Right click the EventManager and choose Run and then, once it is started up,
                    select Window &gt; IDE Tools &gt; Properties to show the NetBeans Platform Properties window.</li>
                <li><p>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/73/prop-display-1.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 alt="" src="../images/tutorials/nodes-2/73/prop-display-2.png"/>
                    </p>

                    <p class="notes"><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 <b>implements PropertyChangeListener</b> {</pre>
                    <p>Press Ctrl-Shift-I to Fix Imports.</p></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>
                    <p class="notes"><b>Note:</b> 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.</p>
                </li>
                <li>Finally, implement the <code>propertyChange()</code> method:
                    <pre class="examplecode">@Override
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 alt="" src="../images/tutorials/nodes-2/73/prop-display-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 alt="" src="../images/tutorials/nodes-2/73/prop-display-4.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&#8212;<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, such as via JavaFX, 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 <tt>Presenter.Popup</tt> can provide
                its own component to display in a popup menu;  the same is true for main
                menu items using <tt>Presenter.Menu</tt>, and toolbar items using <tt>Presenter.Toolbar</tt>.</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%208.0%20Module%20Tutorial">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>
