Geertjan's Blog

  • April 3, 2009


Geertjan Wielenga
Product Manager
I tried the new org.netbeans.api.core.ide.ServicesTabNodeRegistration today. It worked for me, the code below creates a Root node in the Services window (#DISPLAYNAME points to a key in the Bundle), with the children being the three names defined in the ChildFactory:
@ServicesTabNodeRegistration(displayName = "#DISPLAYNAME",
iconResource = "/org/demo/country/node/icon.png", name = "")
public class RootNode extends AbstractNode {
public RootNode() {
super(Children.create(new DemoNodeFactory(), true));
static class DemoNodeFactory extends ChildFactory {
protected boolean createKeys(List list) {
String[] names = {"Tom", "Dick", "Harry"};
for (String name : names) {
return true;
protected Node createNodeForKey(String name) {
Node node = new AbstractNode(Children.LEAF);
return node;

Compare that to the code here and the only difference is that I now don't need to do anything at all in the layer.xml.

I'm surprised, though, that (1) the attributes 'displayName', 'iconResource', and 'name' all appear to be mandatory and that (2) the annotation is set on a Node, instead of on a Children object. Probably I don't understand it completely yet.

Join the discussion

Comments ( 6 )
  • Jesse Glick Friday, April 3, 2009

    The annotation is on a Node, not a Children, because the moment the user expands the node or gets its context menu, the real Node is swapped into the tab in place of the dummy node. The real node could have a rich context menu, drag-n-drop behavior, whatever; whereas the dummy node is quick to load (no class loading from your module is required).

    The label and icon are mandatory because it would look very bad for a node to be missing either.

    The (code) 'name' attr could probably be made optional, defaulted say to the class(+method) name. File an RFE if you like.

  • Geertjan Wielenga Saturday, April 4, 2009

    Thanks, now it makes sense -- the annotation provides a dummy node. So, the icon and display name of the dummy node should be the same as the real node, right? (In which case, why can't the annotation get that information from the real node?)

    And, whether the 'name' attribute is mandatory or not, what's its purpose?

  • Jesse Glick Saturday, April 4, 2009

    Yes, the annotation fields should match those of the real node. They cannot be inferred from the real node because the annotation can use only compile-time constants, whereas the real node could be running arbitrary computations:

    @ServicesTabNodeRegistration(..., displayName="???")

    public class MyNode extends AbstractNode {

    public MyNode() {super(Children.LEAF};}

    public @Override String getDisplayName() {

    if (isPrime(436798769715643961587888934267)) {

    return "Yes it is prime";

    } else {

    return "Nope, composite";




    Node.name serves two functions: (1) it is what is changed when you rename a node in place using F2, if supported; (2) it is used when creating paths, e.g. to persist expansion state of a tree (see NodeOp), in which case it should be unique among siblings.

  • Geertjan Wielenga Saturday, April 4, 2009

    Thanks. Makes perfect sense.

  • Sarah Sunday, April 5, 2009

    I recently came across your blog and have been reading along. I thought I would leave my first comment. I don't know what to say except that I have enjoyed reading. Nice blog. I will keep visiting this blog very often.



  • Eduardo Costa Friday, December 18, 2009

    Have you tryed it with a Maven project, instead of an Ant one? For some dumb reason, it does not recognize the package (even after adding org-openide-code-ide)...

Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.