| <!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 System Properties Module Tutorial for NetBeans Platform 6.5</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="gwielenga@netbeans.org"/> | |
| <meta name="indexed" content="y"/> | |
| <meta name="description" | |
| content="A short guide to using the Nodes API."/> | |
| <!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. --> | |
| <!-- Use is subject to license terms.--> | |
| </head> | |
| <body> | |
| <h1>NetBeans System Properties Module Tutorial</h1> | |
| <p>This tutorial is intended to demonstrate aspects of the <a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/package-summary.html">NetBeans Nodes API</a>.</p> | |
| <p><b>Contents</b></p> | |
| <p><img src="../images/articles/68/netbeans-stamp-65-67-68.gif" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 6.5, 6.7, 6.8" title="Content on this page applies to NetBeans IDE 6.5, 6.7, 6.8"/> </p> | |
| <ul class="toc"> | |
| <li><a href="#gettingtoknowthesample">Getting to Know the Sample</a> | |
| <ul> | |
| <li><a href="#introducing-sample">Introducing the Sample</a></li> | |
| <li><a href="#introducing-sources">Introducing the Sources</a></li> | |
| </ul></li> | |
| <li><a href="#settingupthemoduleproject">Setting Up the Module Project</a> | |
| <ul> | |
| <li><a href="#creatingthemoduleproject">Creating the Module Project</a></li> | |
| <li><a href="#specifying">Specifying the Module's Dependencies</a></li> | |
| </ul></li> | |
| <li><a href="#creatingandgettingtoknowthemainfiles">Creating the Main Files</a> | |
| <ul> | |
| <li><a href="#AllPropsNode"><tt>AllPropsNode.java</tt></a></li> | |
| <li><a href="#PropertiesNotifier"><tt>PropertiesNotifier.java</tt></a></li> | |
| <li><a href="#AllPropsChildren"><tt>AllPropsChildren.java</tt></a></li> | |
| <li><a href="#OnePropNode"><tt>OnePropNode.java</tt></a></li> | |
| <li><a href="#RefreshPropsAction"><tt>RefreshPropsAction.java</tt></a></li> | |
| </ul></li> | |
| <li><a href="#finetuning">Setting Up the Supporting Files</a></li> | |
| <li><a href="#building">Building and Installing the Module</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 6.5 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<br/>version 5</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <!-- ===================================================================================== --> | |
| <h2><a name="gettingtoknowthesample"></a>Getting to Know the Sample</h2> | |
| <p>This tutorial will help you understand the following:</p> | |
| <ul> | |
| <li>how to add a hierarchy of nodes to the Services window</li> | |
| <li>how to rename and delete nodes</li> | |
| <li>how to to display subnodes</li> | |
| <li>how to change the list of nodes</li> | |
| <li>how to create a property sheet</li> | |
| <li>how to assign properties</li> | |
| <li>how to perform other common tasks</li></ul> | |
| <p>Working through this sample is | |
| important because the <a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/package-summary.html">NetBeans Nodes API</a> is one of the more ubiquitous APIs and reflects | |
| information that exists independently of the nodes. You interact | |
| through an interface to this live information.</p> | |
| <p>Before you start writing the module, you have to make sure you have all of the necessary software. | |
| In addition, you might want to play with the sample before building it yourself. Getting to know the | |
| sample lets you know what you are in for during the rest of this tutorial!</p> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="installing-sample"></a>Installing the Sample</h3> | |
| <p>In this section, we download and install the sample, so that we can become | |
| acquainted with it before recreating it ourselves. | |
| <ol><li>Unzip the <a href="https://netbeans.org/files/documents/4/501/SystemProperties.zip">attached file</a>. | |
| <li><p>In the IDE, choose File > Open Project and browse to the folder that contains the unzipped file. | |
| Open the module project. It should look as follows:</p> | |
| <p><img src="../images/tutorials/sysprops/nbm-sysprops-65-2.png" alt="All source files."> | |
| <li>Right-click the project node and choose Install/Reload in Target Platform. The target | |
| platform opens and the module is installed.</ol> | |
| <h3 class="tutorial"><a name="introducing-sample"></a>Introducing the Sample</h3> | |
| <p>In this section, we look at the functionality provided by the module, from | |
| the perspective of an end user. Once we know in detail what the module will provide, | |
| we will be in a better position to build it from scratch. | |
| <ol> | |
| <li><p>Open the Services window (Ctrl-5) and notice that you have a new node with a large number (~50) of subnodes, | |
| each labeled according to a key for specific Java properties:</p> | |
| <p><img src="../images/tutorials/sysprops/nbm-sysprops-65-1.png" alt="System Properties module."> | |
| <p> Contextual menu items appear when you | |
| right-click the main node and subnodes. For the subnodes, the Java | |
| runtime's generalized properties are used to configure basic mechanisms such as | |
| search paths for fonts, location of the Java Virtual Machine (JVM), default locale, | |
| and so on. These are typically string keys, similar to <tt>name.name.name</tt>, and an | |
| associated string value. Values can be queried or set from within the Java language. | |
| In addition, they can be used to set default values at JVM start up. When the System Properties node is | |
| extended, it will display one node for each of the keys, each labeled according to the | |
| key. For example:</p> | |
| <ul> | |
| <li>The value <tt>java.vm.vendor</tt> may display the value Sun Microsystems, Inc., | |
| for example. | |
| <li>The value <tt>path.separator</tt> may display a semicolon, depending on your | |
| configuration. | |
| <li>The value <tt>user.language</tt> may display the value English, depending on your | |
| configuration.</ul> | |
| <li>Play with the sample: | |
| <p><ul><li><b>Show the property sheet.</b> Right-click a subnode and choose Properties. | |
| The property sheet is displayed with a single Properties tab, | |
| containing two properties. The first property is labeled Name and | |
| it gives the same name as the node (key), while the other is labeled Value and | |
| displays the string value of the property. | |
| <li><b>Rename a property.</b> Click on a subnode and then click it again. This lets you rename a key in | |
| place, while keeping the same value. Alternatively, click | |
| on the Name property in the property sheet, or right-click a subnode and choose Rename. | |
| <li><b>Change a value.</b> Click on the Value tab in the property sheet and type in a new value. This | |
| resets the system property to the entered value. | |
| <li><b>Add a property.</b> Right click the main System Properties node and choose Add System Property. This lets you add a new system property | |
| to the list. | |
| <li><b>Delete a property.</b> Select a property and press Delete. This removes the property. | |
| <li><b>Refresh the list.</b> Right click the main System Properties node and choose Refresh. This prompts the module | |
| to recheck the values, refreshing the list as needed.</ul></ol> | |
| </p> | |
| <h3 class="tutorial"><a name="introducing-sources"></a>Introducing the Sources</h3> | |
| <p>The System Properties sample consists of main files and supporting files.</p> | |
| <ul><li><p><b>Main Files.</b> The module's main files are its Java classes (selected in the illustration below):</p> | |
| <p><img border="1" src="../images/tutorials/sysprops/main-files.png" alt="Main files."> | |
| <p>The Java classes are introduced in alphabetical order below: | |
| <p><table width="76%" border="1"> | |
| <tbody><tr> | |
| <td> | |
| <div align="left"><b>File</b></div> | |
| </td> | |
| <td> | |
| <div align="left"><b>Description</b></div> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top"><tt>AllPropsChildren.java</tt></td> | |
| <td> | |
| This children object is responsible for keeping track of the list of nodes underneath | |
| the System Properties node. When first asked for the list, it retrieves all system | |
| properties and asks the node implementation to keep track of all the system | |
| property names. The interface for doing this is a class called Children. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top"><tt>AllPropsNode.java</tt></td> | |
| <td> | |
| This node specifies what children will be under it, and asks to use | |
| AllPropsChildren to keep track of the list of child nodes. The module takes care | |
| of things such as its context menu. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top"><tt>OnePropNode.java</tt></td> | |
| <td> | |
| This is the node representing a single property, and is an AbstractNode. Its | |
| constructor requires that the user supply the key, in the form of a string. For every | |
| system property name, OnePropNode is used to display it. When the user expands | |
| the system properties node, it builds a list of keys, then creates a corresponding | |
| number of OnePropNodes. Each OnePropNode displays a single key, and does not | |
| directly interact with its parent node -- its knowledge is limited to a single system | |
| property and how to deal with it, as well as notifying the PropertiesNotifier | |
| if there are any changes.This design makes it easier to reuse such nodes, including | |
| placing them in other contexts. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top"><tt>PropertiesNotifier.java</tt></td> | |
| <td> | |
| Manages routing events whenever there are changes, including adding, deleting, | |
| or renaming a property, or when a property value has changed. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top"><tt>RefreshPropsAction.java</tt></td> | |
| <td> | |
| This action appears in the pop-up menu under System Properties with the label Refresh. | |
| It forces a refresh to occur, updating the display of information based | |
| on the current state of system properties. | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <li><p><b>Supporting Files.</b> The module's supporting files are in the <tt>org.myorg.systemproperties</tt> package and | |
| in the Important Files node (selected in the illustration below): | |
| <p><img border="1" src="../images/tutorials/sysprops/supporting-files.png" alt="Supporting files."> | |
| <p>The supporting files in the <tt>org.myorg.systemproperties</tt> package are introduced in alphabetical order below: | |
| <p><table width="76%" border="1"> | |
| <tbody><tr> | |
| <td> | |
| <div align="left"><b>File</b></div> | |
| </td> | |
| <td> | |
| <div align="left"><b>Description</b></div> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top"><tt>allPropsIcon.gif</tt></td> | |
| <td>Icon for the System Properties node.</td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top"><tt>Bundle.properties</tt></td> | |
| <td> | |
| This is a standard Java properties file, which uses the syntax <tt>Key=Value</tt>. Keys are | |
| code names for things that appear in the source code, with values designating those | |
| things which will be displayed to the user. | |
| This file is useful for localization. For example, by creating a properties file such | |
| as <tt>Bundle_ja.properties</tt>, and filling all the values with Japanese, this module will automatically display | |
| everything in Japanese, if the | |
| user is running the IDE in Japanese mode. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top"><tt>layer.xml</tt></td> | |
| <td> | |
| Registers <tt>AllPropsNode.java</tt> as a node in Services window. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top"><tt>onePropIcon.gif</tt></td> | |
| <td> | |
| Icon for subnodes. | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <p>The files in the Important Files node are introduced in the order in which they appear in the Projects window: | |
| <p><table width="76%" border="1"> | |
| <tbody><tr> | |
| <td> | |
| <div align="left"><b>File</b></div> | |
| </td> | |
| <td> | |
| <div align="left"><b>Description</b></div> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top">Module Manifest</td> | |
| <td>Declares project as module.</td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top">Build Script</td> | |
| <td> | |
| Contains Ant targets for building the project. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top">Project Metadata</td> | |
| <td> | |
| Contains project metadata, such as dependencies, for project. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top">Project Properties</td> | |
| <td>Contains project properties.</td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top">NetBeans Platform Config</td> | |
| <td>Contains platform properties.</td> | |
| </tr> | |
| <tr> | |
| <td align="left" valign="top">Per-user NetBeans Platform Config</td> | |
| <td>Contains user-specific properties.</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| <br /> | |
| <!-- ===================================================================================== --> | |
| <h2><a name="settingupthemoduleproject"></a>Setting Up the Module Project</h2> | |
| <p>Before you start writing the module, you have to make sure you | |
| that your project is set up correctly. <a href="http://www.netbeans.info/downloads/download.php?a=n&p=1">NetBeans IDE Dev</a> provides a wizard that sets up all the basic files | |
| needed for a module.</p> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="creatingthemoduleproject"></a>Creating the Module Project</h3> | |
| <p>In this section, we use the New Module wizard to create the source structure needed by all | |
| module projects. | |
| <ol> | |
| <li>Choose File > New Project (Ctrl+Shift+N). Under Categories, select NetBeans Modules. | |
| Under Projects, select Module. Click Next.</li> | |
| <li>In the Name and Location panel, type <tt>SystemProperties</tt> in the Project Name field. | |
| Change the Project Location to any directory on your computer. Leave the Standalone Module option | |
| and Set as Main Project checkbox selected. Click Next.</li> | |
| <li>In the Basic Module Configuration panel, type <tt>org.myorg.systemproperties</tt> | |
| in Code Name Base. | |
| <li>Select "Generate XML Layer". Leave the | |
| locations of both the localizing bundle and the XML layer file | |
| so that they will be stored in a package with | |
| the name <tt>org/myorg/systemproperties</tt>. Click Finish.</li> | |
| </ol> | |
| <p> The IDE creates the <tt>System Properties</tt> | |
| project. The project contains all of your sources and | |
| project metadata, such as the project's Ant build script. The project | |
| opens in the IDE. You can view its logical structure in the Projects window (Ctrl-1) and its | |
| file structure in the Files window (Ctrl-2). For example, the Projects window should now look as follows: | |
| <p align="left"><img src="../images/tutorials/sysprops/initial-projects-view.png" border="1" alt="Initial Projects window."> | |
| <h3 class="tutorial"><a name="specifying"></a>Specifying the Module's Dependencies</h3> | |
| <p>Later, you will need to subclass several classes that belong to NetBeans APIs. | |
| Each NetBeans API, provided by a module, has to be declared as a module dependency. | |
| Use the Project Properties dialog box for this purpose, as explained below. | |
| <ol> | |
| <li>In the Projects window, right-click the <tt>System Properties</tt> project and choose Properties. | |
| In the Project Properties dialog box, click Libraries and then click Add... Start typing 'CallableSystemAction', | |
| which is one of the NetBeans API classes you will need later. As you type, notice that the filter narrows, | |
| displaying only those modules that can provide the class that you are typing, as shown below:</p> | |
| <p align="left"><img src="../images/tutorials/sysprops/nbm-moddependencies.png" border="1" alt="Basic Module Configuration panel."></li> | |
| <li>For each of the following APIs, click "Add..." in the Libraries panel, | |
| select the name from the Module list, and then click OK to confirm it: | |
| <p><ul> | |
| <li><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-actions/overview-summary.html">Actions API</a></tt> | |
| <li><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-dialogs/overview-summary.html">Dialogs API</a></tt> | |
| <li><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/overview-summary.html">Nodes API</a></tt> | |
| <li><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-util/overview-summary.html">Utilities API</a></tt> | |
| <li><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-windows/overview-summary.html">Window System API</a></tt> | |
| </ul> | |
| <p>Click OK to exit the Project Properties dialog box. | |
| <li>In the Projects window, double-click Project Metadata and note that the APIs you selected have been | |
| declared as Module dependencies.</li> | |
| </ol> | |
| </div> | |
| <br /> | |
| <!-- ===================================================================================== --> | |
| <h2><a name="creatingandgettingtoknowthemainfiles"></a>Creating the Main Files</h2> | |
| <p>The meat of the Module is provided by its Java classes. In this section, you will create and examine each of them: | |
| <ul> | |
| <li><a href="https://netbeans.org/files/documents/4/492/AllPropsNode.java"><tt>AllPropsNode.java</tt></a> | |
| <li><a href="https://netbeans.org/files/documents/4/494/PropertiesNotifier.java"><tt>PropertiesNotifier.java</tt></a> | |
| <li><a href="https://netbeans.org/files/documents/4/491/AllPropsChildren.java"><tt>AllPropsChildren.java</tt></a> | |
| <li><a href="https://netbeans.org/files/documents/4/493/OnePropNode.java"><tt>OnePropNode.java</tt></a> | |
| <li><a href="https://netbeans.org/files/documents/4/495/RefreshPropsAction.java"><tt>RefreshPropsAction.java</tt></a> | |
| </ul> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="AllPropsNode"></a>AllPropsNode.java</h3> | |
| <p>This Java class specifies what children will be under the main node, and asks to use | |
| <tt>AllPropsChildren</tt> to keep track of the list of child nodes. The Module takes care | |
| of things such as its context menu. | |
| <p>Do the following: | |
| <ol> | |
| <li><b>Create the file.</b> Right-click the <tt>org.myorg.systemproperties</tt> node and choose New > Other. Under | |
| Categories, choose Java Classes. Under File Types, choose Java Class. | |
| Click Next and type <tt>AllPropsNode</tt> in Class Name. Click Finish. The new Java class opens in the Source Editor. | |
| Replace the default code with code found <a href="https://netbeans.org/files/documents/4/492/AllPropsNode.java">here</a>. | |
| <li><b>Understand the file.</b> Here is an explanation of the class: | |
| <ul> | |
| <li><b><tt>public class AllPropsNode extends <a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/AbstractNode.html">AbstractNode</a></tt>.</b> <tt>AbstractNode</tt> is a generic Node subclass. <tt><a href="http://www.netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Node.html">Node</a></tt> is the abstract | |
| class, <tt>AbstractNode</tt> is the common implementation that can be customized. | |
| <li><b><tt>private static ResourceBundle bundle = NbBundle.getBundle(AllPropsNode.class)</tt>.</b> Loads the <tt>Bundle.properties</tt> file for all localized text | |
| for this class. The rest of the class uses the variable bundle to get all localized text. | |
| Note that the other classes do something similar. | |
| <li><b>Constructor:</b> | |
| <ul> | |
| <li><b><tt>public AllPropsNode</tt>.</b> In creating this node, it first calls super -- the <a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/AbstractNode.html#AbstractNode(org.openide.nodes.Children)">constructor | |
| for the super class (AbstractNode)</a>. This creates the infrastructure for | |
| AbstractNode, and shows that it is mandatory to supply a child object for its | |
| use. This object represents the list of children of the node, creating a separate class | |
| for clarity: AllPropsChildren. | |
| <ul> | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/AbstractNode.html#setIconBase(java.lang.String)">setIconBase</a></tt>.</b> Designates the location for the associated icon. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/AbstractNode.html#setName(java.lang.String)">setName</a></tt>.</b> Sets the internal name. This is usually arbitrary but ideally should be | |
| unique among siblings. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Node.html#setDisplayName(java.lang.String)">setDisplayName</a></tt>.</b> Sets the name the user sees. This defaults to the internal name, | |
| but it is better to set it to something localized. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Node.html#setShortDescription(java.lang.String)">setShortDescription</a></tt>.</b> Sets the associated tool tip. This is the override to specify | |
| what goes into the node context menu. | |
| </ul></ul> | |
| <li><b>Methods:</b> | |
| <ul> | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Node.html#getActions(boolean)">getActions</a></tt>.</b> The following is a list of actions to be | |
| displayed in the menu, with separators between the menu items. The following | |
| methods are used: | |
| <ul> | |
| <li><tt>RefreshPropsAction</tt> is an action defined in another source file | |
| <li><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-actions/org/openide/actions/NewAction.html">NewAction</a></tt> enables the creation of a new subnode or key-value pair | |
| <li><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-actions/org/openide/actions/OpenLocalExplorerAction.html">OpenLocalExplorerAction</a></tt> permits the user to make a new Explorer window | |
| showing only system properties | |
| </ul> | |
| <p>Both <tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-actions/org/openide/actions/ToolsAction.html">ToolsAction</a></tt> and <tt><a href="http://www.netbeans.org/download/dev/javadoc/org-openide-actions/org/openide/actions/PropertiesAction.html">PropertiesAction</a></tt> are standard actions that most nodes | |
| should have. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/AbstractNode.html#getHelpCtx()">getHelpCtx</a></tt>.</b> Supplies an IDE key for the context help. When building context help | |
| for this Module, this is how you would associate a specific node with a | |
| specific help string. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/AbstractNode.html#cloneNode()">cloneNode</a></tt>.</b> Creates a new copy of the node that enables other parts of the IDE to | |
| display a separate copy of the System Properties list, other than the Runtime tab. | |
| This is more efficient than the fallback implementation, which is to delegate to the | |
| original. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/AbstractNode.html#getNewTypes()">getNewTypes</a></tt>.</b> Returns a list of <tt><a href="http://www.netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/datatransfer/NewType.html">NewType</a></tt> objects. When | |
| there is <tt>NewAction</tt> in the context menu, this action displays menu items | |
| corresponding to each of the <tt>NewTypes</tt> in the node. The action provides the actual | |
| GUI, such as showing a submenu. You specify abstract definitions | |
| and make the new objects. In this example, only one <tt>NewType</tt> is returned, | |
| since there is only one type of thing that can reasonably be created (a new system | |
| property); however, more than one <tt>NewType</tt> could be returned, and they would be | |
| displayed in a submenu. Following this method is the definition of the name on the | |
| menu item, such as New System Property, and the help context. | |
| <ul><li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/datatransfer/NewType.html#create()">create</a></tt>.</b> Creates the new object. In this example, there | |
| will be dialog boxes for the key-in values. | |
| <ul> | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-dialogs/org/openide/NotifyDescriptor.InputLine.html">NotifyDescriptor.InputLine</a></tt>.</b> The description of a small dialog with a single | |
| text entry field pop up, a title for the dialog, and a message. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-dialogs/org/openide/DialogDisplayer.html#notify(org.openide.NotifyDescriptor)">DialogDisplayer.getDefault().notify(desc)</a></tt>.</b> Displays all this in a pop-up dialog. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-dialogs/org/openide/NotifyDescriptor.InputLine.html#getInputText()">getInputText</a></tt>.</b> Retrieves the user input for the key. | |
| <p>The same is done for the value, again using <tt>DialogDisplayer.getDefault</tt> and | |
| <tt>getInputText</tt>. | |
| <p>Next, <tt>System.setProperty</tt>, from the Java API, is called to set the system | |
| property. | |
| <p>Finally, another class, <tt>PropertiesNotifier.changed</tt> (created next), is called to indicate | |
| to other classes and Module components that something about the current set of | |
| system properties has changed and updates are required. For example, there may | |
| be a new property, or an existing value may have changed. | |
| </ul> | |
| </ul></ul> | |
| </ul> | |
| </ol> | |
| <h3 class="tutorial"><a name="PropertiesNotifier"></a>PropertiesNotifier.java</h3> | |
| <p>This Java class manages routing events whenever there are changes, including adding, deleting, | |
| or renaming a property, or when a property value has changed. You could also see it as a helper routine, very similar | |
| to a JavaBeans component | |
| that has an event set attached to it. However, it is not strictly a JavaBeans component -- there | |
| are no instances of this class -- but its static methods are used like JavaBeans | |
| instance methods. | |
| <ol> | |
| <li><b>Create the file.</b> Right-click the <tt>org.myorg.systemproperties</tt> node, choose New > Java Class, | |
| and type <tt>PropertiesNotifier</tt> in Class Name. Click Finish. The new Java class opens in the Source Editor. | |
| Replace the default code with code found <a href="https://netbeans.org/files/documents/4/494/PropertiesNotifier.java">here</a>. | |
| <li><b>Understand the file.</b> The methods defined for this class are as follows: | |
| <p><ul><li><b><tt><a name="PropertiesNotifierchanged" id="PropertiesNotifierchanged"></a>changed</tt>.</b> Fires an event to those processes that are listening. Every component that | |
| displays information based on a system property must listen for these events and | |
| update their displays as needed. | |
| <li><b><tt>addChangeListener</tt></b> and <b><tt>removeChangeListener</tt>.</b> Let components register | |
| themselves as listeners for these events. Processes which have displayed state can | |
| add a <tt>ChangeListener</tt> to this class. To ensure proper updates, processes that | |
| affect the state call <tt>changed</tt>.</ul></ol> | |
| <h3 class="tutorial"><a name="AllPropsChildren"></a>AllPropsChildren.java</h3> | |
| <p>This Java class is responsible for keeping track of the list of nodes underneath | |
| the System Properties node. When first asked for the list, it retrieves all system | |
| properties and asks the node implementation to keep track of all the system | |
| property names. The abstract class doing this is called <tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Children.html">Children</a></tt>. | |
| <p>In this example, a popular children implementation called <tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Children.Keys.html">Children.Keys</a></tt> is used. | |
| By subclassing <tt>Children.Keys</tt>, you need not explicitly keep track of | |
| the nodes -- this implementation does that. Instead, you keep track | |
| of a set of keys, which are lighter weight objects. Each key typically represents one | |
| node. You must tell the implementation how to create a | |
| node for each key. You can decide for yourself what type of keys to | |
| use. | |
| <p>In this example, the keys are names of system properties. | |
| <ol> | |
| <li><b>Create the file.</b> Right-click the <tt>org.myorg.systemproperties</tt> node, choose New > Java Class, | |
| and type <tt>AllPropsChildren</tt> in Class Name. Click Finish. The new Java class opens in the Source Editor. | |
| Replace the default code with code found <a href="https://netbeans.org/files/documents/4/491/AllPropsChildren.java">here</a>.</li> | |
| <li><b>Understand the file.</b> The important methods that should be defined when implementing | |
| <tt>Children.Keys</tt> include: | |
| <ul><li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Children.html#addNotify()">addNotify</a></tt>.</b> Called the first time that a list of | |
| nodes is needed by the platform. An example of this is when the System Properties node | |
| is expanded. When <tt>addNotify</tt> is called, it calls the helper method <tt>refreshList</tt> | |
| to determine the keys, then it registers itself with the <tt>PropertiesNotifier</tt>, | |
| requesting notification of any system property changes. If there is such a change, | |
| the list will be refreshed. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Children.html#removeNotify()">removeNotify</a></tt>.</b> Called when the user collapses a System Properties node and | |
| starts working on something else. The platform will notice that the list of nodes is | |
| no longer needed, and it will free up the memory that is no longer being used. | |
| Note that momentarily collapsing the node will not trigger this call. When | |
| <tt>removeNotify</tt> is called, it removes the listener, as it is no longer interested in | |
| receiving notifications. In addition, <tt>setKeys</tt> is called with an empty set. This method | |
| is defined by <tt>Children.Keys</tt> for use by the subclasses. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Children.Keys.html#createNodes(java.lang.Object)">createNodes</a></tt>.</b> Called by the implementation whenever it needs to construct a | |
| child node. It is passed the key for which it is making a node. It returns either none, | |
| one, or more nodes corresponding to what should be displayed for the key. In this | |
| example, a new instance of one property node is being created, and the system | |
| property name is passed into its constructor. | |
| <li><b><tt>refreshList</tt>.</b> The <tt>System.getProperties</tt> call retrieves all of the properties | |
| currently defined in the system. This call goes through all of the property names, | |
| keeping and sorting this list. <tt>setKeys</tt> is called with the list, enabling the | |
| subnodes to appear, one per system property, sorted by property name.</ul> | |
| </ol> | |
| <h3 class="tutorial"><a name="OnePropNode"></a>OnePropNode.java</h3> | |
| <p>This Java class provides the <tt>AbstractNode</tt> implementation for a single property. | |
| Its constructor requires a string key. This class displays a single system property name. When the user expands | |
| the system properties node, it builds a list of keys, then creates a corresponding | |
| number of <tt>OnePropNodes</tt>. Each <tt>OnePropNode</tt> displays a single key, and does not | |
| directly interact with its parent node -- its knowledge is limited to a single system | |
| property and how to deal with it, as well as notifying the <tt>PropertiesNotifier</tt> | |
| if there are any changes. This design makes it easier to reuse such nodes, including | |
| placing them in other contexts. | |
| <ol> | |
| <li><b>Create the file.</b> Right-click the <tt>org.myorg.systemproperties</tt> node, choose New > Java Class, | |
| and type <tt>OnePropNode</tt> in Class Name. Click Finish. The new Java class opens in the Source Editor. | |
| Replace the default code with code found <a href="https://netbeans.org/files/documents/4/493/OnePropNode.java">here</a>.</li> | |
| <li><b>Understand the file.</b> Here is an explanation of the class: | |
| <ol> | |
| <li><b><tt>public class OnePropNode extends AbstractNode</tt>.</b> <tt>AbstractNode</tt> is a generic Node subclass. <tt>Node</tt> is the abstract | |
| class, <tt>AbstractNode</tt> is the common implementation that can be customized. | |
| <li><b><tt>private static ResourceBundle bundle = <a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/NbBundle.html#getBundle(java.lang.Class)">NbBundle.getBundle(AllPropsNode.class)</a></tt>.</b> Loads the <tt>Bundle.properties</tt> file for all localized text | |
| for this class. The rest of the class uses the variable bundle to get all localized text. | |
| <li><b>Constructor:</b> | |
| <ul> | |
| <li><b><tt>super(<a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Children.html#LEAF">Children.LEAF</a>)</tt>.</b> Tells the node�s hierarchy that this | |
| is a leaf node that will not need to be expanded and will not have any children. It | |
| then stores the key and sets the icon. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/AbstractNode.html#setDefaultAction(org.openide.util.actions.SystemAction)">setDefaultAction</a></tt>.</b> Sets what is run by default if the node is double clicked or | |
| similar user actions are performed. In this example, the default action is to pop up | |
| the property sheet. | |
| <li><b><tt>super.<a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/AbstractNode.html#setName(java.lang.String)">setName(key)</a></tt>.</b> Sets the name of the key. The inherited version is used, | |
| to set the node name (it does not attempt to rename the actual property).. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Node.html#setShortDescription(java.lang.String)">setShortDescription</a></tt>.</b> Sets the associated tool tip. This is the override to specify | |
| what goes into the node context menu. | |
| </ul> | |
| <li><b>Methods:</b> | |
| <ul> | |
| <li><b><tt>createSheet</tt>.</b> Configures the look of | |
| the property sheet. This creates the list of tabs in the property sheet, along with the | |
| list of properties. <tt>createSheet</tt> is not called until there is a need to display the list | |
| of properties. | |
| <ul> | |
| <li><b><tt>super.<a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/AbstractNode.html#createSheet()">createSheet</a></tt>.</b> Ensures there is a sheet to start with. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Sheet.html#get(java.lang.String)">sheet.get (Sheet.PROPERTIES)</a></tt>.</b> Checks to see if there is a tab named | |
| <tt>Properties</tt>. If not, <tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Sheet.html#createPropertiesSet()">Sheet.createPropertiesSet</a></tt> makes one. Note that <tt><a href="http://www.netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Sheet.html">Sheet</a></tt> | |
| refers to the entire set of properties for the node, and <tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Sheet.Set.html">Sheet.Set</a></tt> is one tab in the | |
| property sheet. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/PropertySupport.Name.html">PropertySupport.Name</a></tt>.</b> Creates a <tt>Name</tt> property that reflects | |
| the name of the node. The code is already synchronizing the node name with the | |
| system property name. | |
| <li><b><tt>ValueProp</tt>.</b> Is an inner class, a custom property that is created for this example. | |
| <tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/PropertySupport.ReadWrite.html">PropertySupport.ReadWrite</a></tt> is the base class for entering and viewing values. | |
| The super call provides a code name for the property as well as a display name and | |
| a tool tip for the user. | |
| <ul> | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Node.Property.html#getValue()">getValue</a></tt>.</b> Looks up the system property. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Node.Property.html#setValue(java.lang.Object)">setValue</a></tt>.</b> Sets a new value for the | |
| system property and notifies other processes that the value has changed. | |
| </ul> | |
| <p>The property is added to the property sheet, along with a <tt>ChangeListener</tt>, which | |
| listens for changes in system properties, which may mean that this specific property | |
| has changed. If true, then the <tt>firePropertyChange</tt> node fires a change to say that | |
| one of the properties in its property sheet is no longer valid, and checks and updates | |
| should be made accordingly. Note that the name of the property is value, which | |
| matches the internal name assigned when creating <tt>ValueProp</tt>. | |
| </ul> | |
| <li><b><tt>finalize</tt>.</b> Called when the class is destroyed -- whenever this node | |
| is destroyed, the <tt>ChangeListener</tt> is removed. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/AbstractNode.html#canRename()">canRename</a></tt>.</b> Returns <tt>true</tt>, allowing the node to be renamed. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/AbstractNode.html#setName(java.lang.String)">setName</a></tt>.</b> Called when the node is renamed, such as from the rename action, an inplace | |
| rename from the Explorer, or from the Name property in the property sheet. | |
| This action retrieves all system properties and associated values, removes the key, | |
| adds a new property with a new name and value, and sets the system properties. | |
| This action also notifies all concerned that it has changed, though it does not directly | |
| rename itself (see <tt>AllPropsChildren</tt> next). | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/AbstractNode.html#canDestroy()">canDestroy</a></tt>.</b> Gives permission to delete this node. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-nodes/org/openide/nodes/Node.html#destroy()">destroy</a>.</tt></b> Retrieves system properties, removes its key, sets | |
| properties back, and notifies all concerned of changes. Note that this <tt>destroy</tt> | |
| method does not remove the node -- it only removes the system property and | |
| notifies interested parties that this property is gone. The node is actually removed | |
| later, by <tt>AllPropsChildren</tt>. <tt>AllPropsChildren</tt> realizes this property no longer | |
| exists, and creates a new set of keys that no longer includes this property. Then the | |
| <tt>Children.Keys</tt> implementation automatically removes that node. This is done to | |
| reflect the actual state of the system. | |
| </ul> | |
| </ol></ol> | |
| <h3 class="tutorial"><a name="RefreshPropsAction"></a>RefreshPropsAction.java</h3> | |
| <p>This Java class provides the "Refresh" action that appears in the pop-up menu under the "System Properties" main node. | |
| It forces a refresh to occur, updating the display of information based | |
| on the current state of system properties. It is a <tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/actions/CallableSystemAction.html">CallableSystemAction</a></tt> and is | |
| always enabled, yet is not sensitive to what is selected. In principle, it could also be placed | |
| as a button in a toolbar. | |
| <ol> | |
| <li><b>Create the file.</b> Right-click the <tt>org.myorg.systemproperties</tt> node, choose New > Java Class, | |
| and type <tt>RefreshPropsAction</tt> in Class Name. Click Finish. The new Java class opens in the Source Editor. | |
| Replace the default code with code found <a href="https://netbeans.org/files/documents/4/495/RefreshPropsAction.java">here</a>.</li> | |
| <li><b>Understand the file.</b> The important methods that should be defined when implementing <tt>CallableSystemAction</tt> are: | |
| <p><ul><li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/actions/CallableSystemAction.html#performAction()">performAction</a></tt>.</b> Calls <tt><a href="#PropertiesNotifierchanged">PropertiesNotifier.changed</a></tt> to indicate to other classes | |
| and Module components that something about the current set of system properties has changed and | |
| updates are required. For example, a new property may have been added or an existing value may have been changed. | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/actions/SystemAction.html#getName()">getName</a></tt>.</b> Gets the name of the action's label from <tt>Bundle.properties</tt> | |
| <li><b><tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/actions/SystemAction.html#getHelpCtx()">getHelpCtx</a></tt>.</b> Supplies an IDE key for the context help. When building context help | |
| for this Module, this is how you would associate a specific node with a specific help string. | |
| </ul></ol></p> | |
| <br /> | |
| <!-- ===================================================================================== --> | |
| <h2><a name="finetuning"></a>Setting Up the Supporting Files</h2> | |
| <p>Once you have coded the main files, you must specify how you want your Module to | |
| impact the filesystem and what labels and texts you want to display to the user. The <tt>layer.xml</tt> file | |
| and the <tt>Bundle.properties</tt> file are made for this purpose.</p> | |
| <ol><li>Add the following entry between the <filesystem> tags in the <tt>layer.xml</tt> file: | |
| <pre class="examplecode"><folder name="UI"> | |
| <folder name="Runtime"> | |
| <file name="org.myorg.systemproperties.AllPropsNode.instance" /> | |
| </folder> | |
| </folder></pre> | |
| <li>Add the following properties to the <tt>Bundle.properties</tt> file: | |
| <pre class="examplecode">LBL_AllPropsNode=System Properties | |
| HINT_AllPropsNode=Shows all currently set system properties. | |
| LBL_NewProp=System Property | |
| LBL_NewProp_dialog=Create New Property | |
| MSG_NewProp_dialog_key=New property name: | |
| MSG_NewProp_dialog_value=New property value: | |
| HINT_OnePropNode=Represents one system property. | |
| PROP_value=Value | |
| HINT_value=Value of this system property. | |
| LBL_RefreshProps=Refresh | |
| LBL_MyOwnActionProps=My Own Action</pre> | |
| <li>For the icons used to display the nodes, you can use any 16x16 icons you want, so long as they are | |
| named <tt>allPropsIcon.gif</tt> and <tt>onePropIcon.gif</tt>, which | |
| is what they are named in the code above. Alternatively, | |
| get the icons from the <a href="https://netbeans.org/files/documents/4/501/SystemProperties.zip">ZIP file attached to this tutorial</a>. | |
| Note that the <tt>setIconBase</tt> statements in the constructors of <a href="https://netbeans.org/files/documents/4/492/AllPropsNode.java"><tt>AllPropsNode.java</tt></a> and <a href="http://www.netbeans.org/files/documents/4/493/OnePropNode.java"><tt>OnePropNode.java</tt></a> | |
| set the location of the icons. | |
| </ol> | |
| <br /> | |
| <!-- ======================================================================================= --> | |
| <h2><a name="building"></a>Building and Installing the Module</h2> | |
| <p>Now that you have completed your module, it is time to try it out. | |
| The IDE uses an Ant build script to build and install your module. The build script was created for you | |
| when you created the module project.</p> | |
| <ol> | |
| <li><p>In the Projects window, right-click the <tt>System Properties</tt> project and choose Install/Reload | |
| in Target Platform.</p> | |
| <p>The module is built and installed in the target IDE or Platform. The target IDE or Platform opens so that you | |
| can try out your new Module. The default target IDE or Platform is the | |
| installation used by the current instance of the development IDE. Note that when you run your Module, you will be using | |
| a temporary test user directory, not the development IDE's user directory. | |
| <li><p>In the IDE's Services window (Ctrl-5), you should see the new node, together with its many subnodes:</p> | |
| <p><img src="../images/tutorials/sysprops/nbm-sysprops-65-1.png" alt="System Properties module."></p> | |
| <li>Use the module as described in the <a href="#introducing-sample">Introducing the Sample</a> section. | |
| </ol> | |
| <br> | |
| <div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&subject=Feedback:%20System%20Properties%20Module%20Tutorial">Send Us Your Feedback</a></div> | |
| <br style="clear:both;" /> | |
| <!-- ======================================================================================== --> | |
| <h2><a name="nextsteps"></a>Next Steps</h2> | |
| <p>For more information about creating and developing NetBeans Module, see the following resources: | |
| <ul> | |
| <li><a href="https://netbeans.org/kb/trails/platform.html">Other Related Tutorials</a></li> | |
| <li><a href="https://netbeans.org/download/dev/javadoc/">NetBeans API Javadoc</a></li> | |
| </ul> | |
| <hr> | |
| </body> | |
| </html> |