Common Navigator Tutorial 1: Hello World

The Commons Navigator Framework is one of the more complex parts of the Eclipse API. It can be difficult to get started with the framework, and one of the hardest parts is simply getting a basic navigator to appear with custom content. This tutorial is designed to get you to that point so that you can start exploring the framework on your own.

There are quite a few steps, but it’s not as bad as it looks. So let’s get started!

  • Before creating a navigator, it’s first necessary to have something to place it in. If you don’t have an existing RCP application to work with, create a new one using the “Hello RCP” template. Also, if you have a custom target platform, you’ll need to add the org.eclipse.ui.navigator plug-in to that target. Finally, you’ll need to add the navigator plug-in as a dependency in the appropriate manifest.
  • Now that the preparations are out of the way, we can create the navigator itself. Because CNF navigators are also regular views, the first step is to create an org.eclipse.ui.views extension. Enter in an appropriate id and name, and then enter a new class name in the class field. Note that this is where we diverge from standard CNF usage. Normally we would simply enter the org.eclipse.ui.navigator.CommonNavigator class in this field. To learn why we are not, check out my previous post on the subject.
  • Click on the class field label to launch the New Java Class wizard. Change the superclass to org.eclipse.ui.navigator.CommonNavigator and click Finish. We now have our main navigator class, and we’ll return to it a little later. You can now also add your view to a perspective either programmatically or through a perspective extension. At this point, you should be able to run your application and see an empty navigator appear.

CNF Tutorial 1

  • Now for some content. Create a NavigatorRoot class that will serve as the root node in your navigator. Note that this element will not appear in the navigator, the children of the root node will be the first to appear. The class representing the navigator root must be an IAdaptable, and the simplest way to accomplish this is to have your NavigatorRoot extend the PlatformObject class. Also create another simple bean called ParentBean that has a name attribute. Finally, add a getParentBeans method to your NavigatorRoot class and have that method return a set of populated ParentBean instances.
  • The navigator root can now be added to the navigator class we created above. In that class, override the getInitialInput method and simply return a new instance of NavigatorRoot. Note that in a real-world implementation, the navigator root would probably be a singleton or returned by a factory class. Also note that these few lines of code are all that are required in the navigator subclass. While subclassing the CNF navigator is not ideal, this approach is far from risky.
  • The next step is to declare an org.eclipse.ui.navigator.navigatorContent extension. This extension point is used to define many navigator elements, including content (of course), filters and actions. It’s important to understand that this extension point defines content in a navigator independent way. You will later need to bind this content to a specific navigator to get the content to appear. So create this extension and add a navigatorContent element below it. Choose an appropriate id and name, and then enter class names for the contentProvider and labelProvider fields.
  • Click on the contentProvider and labelProvider field labels to create the required providers. The content provider should take in a NavigatorRoot as input and return an array of ParentBean instances as children. The label provider should simply return the name of the ParentBean as the display text.
  • We now need to specify what will cause our content to appear. The simplest way to do this is to specify what type of parent element should trigger our content and cause our content/label providers to be called. In our example, we’ll add a triggerPoints element below the navigatorContent element. Under triggerPoints, we’ll add an instanceof element and then enter your NavigatorRoot class in the value field. This will cause your content to be added whenever a NavigatorRoot instance is encountered in the tree.
  • The final step (we’re almost there!) is to bind the content to the navigator. To do that, we need to declare an org.eclipse.ui.navigator.viewer extension. This extension point registers our view as a navigator and allows us to bind different types of content to it. Create the extension and first add a viewer element to it. Enter the id of your view in the viewerId field. Now add a viewerContentBinding element below the extension. This element is what actually adds our content into the navigator. Again, enter your view id into the viewerId field. Add an includes element below the viewerContentBinding and then a contentExtension element below that. Finally, in the pattern field of the contentExtension element, enter the id of your navigator content.

You should now be able to run your application and see content appear in the navigator!

CNF Tutorial 2

As you can see, even the simplest CNF example requires a fair number of steps to get working. It’s also rare for the navigator to appear correctly on the first try, and it can be extremely frustrating to debug the CNF when things go wrong. So much of the CNF is wired using extension points that any small typo can cause you a lot of grief. For that reason, I recommend that when working with the CNF you make small, incremental changes and verify functionality after each change.

Because it can be a real pain to get all the linkages working the first time, I’ve created some sample code (Eclipse 3.2, Eclipse 3.3) that will get you up to speed more quickly. Good luck!