BasicUnderstandingOfTheNetBeansNodesAPI

Doc Contributed by Kunal Modi & Anil Raju

Contents


Introduction

I was fascinated to see the new Bean Tree representation in NetBeans6.0 beta. A question then struck me. How are these nodes represented by NetBeans? Whether it is the Project Window, Files Window all use it to represent data. In order to understand this, I had to go through the Node API tutorials on NetBeans and the Documentation. However, though the tutorials did explain a great deal of Nodes API functionalities, a new module developer may take more time to understand the basic flow. Thus I thought of writing this Tutorial. It may stand as a base for enthusiasts interested in flow of control while nodes are being generated dynamically. For e.g. Consider the Collaboration scenario(You can consider the collab plugin). It has a node called as 'Active Conversation'. As soon as a conversation is struck with another user, the other user's name appears below the 'Active Conversation'(For those not familiar with collab, you can refer to NetBeans Tutorial or you may just consider an Offline Online scenario of your favourite messenger). A new node is now created. In this tutorial, we are going to simulate the creation of this new node by a click of a button.

Requirements

Basic knowledge of plugin development(making modules,TopComponent API.)

Overview

So what we plan is to simulate a Contact List in an Online/Offline secenario. We'll provide 2 buttons to simulate this.Pressing the "Developer Online" makes a node representing that Developer and "Developer Offline" button deletes the last developer from the list,thus simulating that the developer has gone offline.

Lets Start

Creating the module.

  • To make a new module go to File--> New Project
  • Select NetBeans Modules from the category and Module from the aside Projects window.
  • Click next.

File:Creating new module

  • Set project name as "NodesDemo" and set a destination project folder and location.
  • Let it be a standalone module. Click next.
  • Rename code name base as "org.modules.sack.nodesdemo" and let other default settings as it is.
  • Click Finish.

After this a new module will appear in the projects window with source package as "org.modules.sack.nodesdemo".

Creating a new TopComponent.

In order to show the files in an explorer window, we need to make a new TopComponent.

  • Right-click on the package folder a choose a new Window Component.
  • Select Window position as Explorer.

File:img4_BasicUnderstandingOfTheNetBeansNodesAPI.JPG

  • Keep the "Open on Application Start" option unchecked.Click next.
  • Set 'NodesUI' as ClassPrefix.

File:img5_BasicUnderstandingOfTheNetBeansNodesAPI.JPG

  • Set an icon. Icon should be a 16X16 .png , .gif file.File:icon_BasicUnderstandingOfTheNetBeansNodesAPI.jpg
  • Click finish.

Designing The UI

The TopComponent gets created. Now we need to design the UI for "NodesUITopComponent.java"

Switch to the designer form for "NodesUITopComponent.java". In the Component Inspector, right click the TopComponent node, and choose Set Layout > BorderLayout.

  • Select the JScrollPane from the Component Palette window and drop the scroll pane on the form such that it covers the entire form.
  • Select your JScrollPane, select its property sheet. Click code tab and edit the "Custom Creation Code". Set this field to new BeanTreeView()". (BeanTreeView and many other components are provided by the Explorer API to represent Nodes).

File:img6_BasicUnderstandingOfTheNetBeansNodesAPI.JPG

  • Add a panel to the same TopComponent below the jScrollPane. To this add two Buttons. Set the text of one of the to "Developer Online" and the other to "Developer Offline".

File:img7_BasicUnderstandingOfTheNetBeansNodesAPI.JPG

Code content:

(Similar to the Pictures Explorer)

  • Now switch to the code editor.
  • In order to display the nodes we need to have an ExplorerManager. Always, representing Node is associated with an ExplorerManager rather than the component. Lets make up an ExplorerManager. Include the following line of code in "NodesUITopComponent.java".
  • ExplorerManager mgr = new ExplorerManager();
  • We will also need to implement an interface
    ExplorerManager.Provider
    to NodesUITopComponent.java.
  • By now many error annotations must have been attached to various lines.
  • Don't worry these are because the appropriate dependencies haven't been found. Lets add the Dependencies one by one.
  • Right click on the projects mode and select properties. go to the library node and click add.
  • A window pops ups. Lets look for our first dependency. Type in "ExplorerManager".

The result will show a org.openide.explorer.ExplorerManager class. Click ok. The Explorer and PropertySheet Module gets added to the dependecies.

  • Similarly look for BeanTreeView and you will find that it is the same dependency module.
  • Click ok and exit the property sheet.
  • A bulb glowing aside each of the previously error annotated line shows an option to import the appropriate class. Otherwise pressing Ctrl+Shft+I will also automatically import the classes.
  • Still a bulb glows at the header notation of the class asking you to implement the abstract methods of ExplorerManager.Provider , clicking it implements the method. Replace the body of the method getExplorerManager() by
return mgr;

This code will return the ExplorerManager associated with the component whenever it is called for.

  • If you run the module now(Right-click project node and select install in target platform), you can see a "NodesUI" option in the Windows menu. Click it. A "NodesUI Window" opens up in the explorer window with an unnamed node and two Buttons.

I would like to mention here that this tutorial is aimed to provide an understanding of the Basic Flow when Nodes are created. A detailed and an excellent tutorial is already present on [| NetBeans website as NetBeans Selection Management Tutorial II—Using Nodes] The above mentioned tutorial gives a detailed information about Node properties and features. We will basically aim at Dynamically creating and deleting a Node.

Logic

  • We plan to have a root node named as "Online". Under this node will lie a list of nodes of all the developers who are Online.Its basically an object, which takes care of the list of children. We can call them a list of Online Developers. Each of these nodes will represent a Developer. Thus the Scenario can described by the image below

File:img9_BasicUnderstandingOfTheNetBeansNodesAPI.JPG For each node we have to associate a view(Graphic Node) and the Data Associated with that node. We will restrict our discussion to level 1. Let us identify the classes.

  1. OnlineDeveloper (will have children)
  2. Developer (Data associated at level 1)
  3. DeveloperNode (Node associated at level 1, will not have Children)
  • Make the Above classes.
  • We will start in Top Down Fashion.
  • At First, let us set the root node. The following code assigns the root node in context to the manager. Add this lines in the constructor of "NodesUITopComponent.java"
mgr.setRootContext(new AbstractNode(childofroot));
mgr.getRootContext().setDisplayName("Online");
  • An error will appear since it is not able to find the AbstractNode Class. We need to add the Nodes API dependency as we did before for Explorer API. To learn more about AbstractNode read the above mentioned Tutorial.
  • To the Constructor of AbstractNode, we are passing "childofroot"."childofroot" is an instance of OnlineDeveloper. Define it at class level of "NodesUITopComponent.java" as
OnlineDeveloper childofroot = new OnlineDeveloper();
  • Define class OnlineDeveloper as follows:
package org.modules.sack.nodesdemo;

import java.util.List;
import org.openide.nodes.Children;
import org.openide.nodes.Node;

/**
 *
 * @author admin
 */
public class OnlineDeveloper extends Children.Keys<Developer> {

    @Override
    protected Node[] createNodes(Object arg0) {
        Developer md = arg0;
        return new Node [] {new DeveloperNode(md)};
    }
    
    public void refreshList(List<Developer> l) {
        setKeys(l);
    }
}

The createNodes (Object key) method—will create the nodes that will be children of your root node. We override this method here and make it to return the array of developer nodes. The list of the nodes is initially empty. Whenever we want to edit this list we will call refreshList(List<Developer> l) with the modified list l. This method invokes the all powerful setKeys(Collection l) which does the remaining work. Every time you want to update the list of nodes, call this method with the list as parameters. Our method refreshList(List<Developer> l) is basically written to access setKeys(Collection l).

  • The above code mentions of the Developer class and the DeveloperNode class. Let us check them out.
  • As i mentioned that the Developer class will hold the data to the related DeveloperNode class. The structure of the code is as follows
package org.modules.sack.nodesdemo;

/**
 *
 * @author admin
 */
class Developer {
    int id;
    Developer(int i) {
        this.id = i;
    }
    protected int getid(){
        return id;
    }
}
  • For basic functionality we are just associating an id for each Developer.(You could save much more...)
  • Let us understand the structure of class DeveloperNode
package org.modules.sack.nodesdemo;

import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;

/**
 *
 * @author admin
 */
class DeveloperNode extends AbstractNode {
    public DeveloperNode(Developer md) {
        super(Children.LEAF);
        setName("Developer "+md.getid());
    }
}
  • This class is responsible for making node.
     super(Children.LEAF); 
    says that this is the leaf node. If you further want to classify, then we need to go one more level deeper. But we will restrict our discussion till here.
  • Now the Logic is Done!!! All we need to is to setup the controller.

Controller

  • Let us move back to NodesUITopComponent.java. We declare a static list which we will refer as Online List. This list will be controlled by the two controllers we made. Buttons --> Developer Online and Developer Offline. Also, we define a static counter.
    static List<Developer> l = new ArrayList();
    static int counter;
  • Make the necessary imports.
  • The Final steps. We need to define the actionPerformed by our two controller buttons. It should look something like this -
private void DeveloperOnlineActionPerformed(java.awt.event.ActionEvent evt) {
        l.add(new Developer(++counter));
        childofroot.refreshList(l);
    }

    private void DeveloperOfflineActionPerformed(java.awt.event.ActionEvent evt) {
                if(counter!=0 ){
                l.remove(--counter);
        childofroot.refreshList(l);
        }
    }
  • Above code basically creates a New Developer and adds it to our list. This List is then passed to the refreshList which indirectly calls setKeys and updating our List of Developers who are online. On the other hand, DeveloperOffline button removes the last Developer from the list and refreshes the list.
  • Now Clean and Build the project.

File:img10_BasicUnderstandingOfTheNetBeansNodesAPI.JPG

  • Run the project.

File:img11_BasicUnderstandingOfTheNetBeansNodesAPI.JPG

  • Now from the Target Platform Window choose "NodesUI".

File:img12_BasicUnderstandingOfTheNetBeansNodesAPI.JPG

  • Our "NodesUI window will appear on the Explorer Area"

File:img13_BasicUnderstandingOfTheNetBeansNodesAPI.JPG

  • Press "DeveloperOnline" and a new nodes get created at runtime and now appears in the "Online" list.

File:img14_BasicUnderstandingOfTheNetBeansNodesAPI.JPG

  • Similarly, Press "DeveloperOffline" and the last node generated gets deleted from the list.

File:img15_BasicUnderstandingOfTheNetBeansNodesAPI.JPG

Things to be Noted.

  • The NodesAPI provides a good number of features like popmenu, Actions,FilterNode etc, which otherwise would require hand coding in case of JTrees and JLists.
  • The classes provided by NodesAPI suffice almost all requirements.
  • An overview of this API is available here

References

Attachments

Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo