Adding a History Tab, and Other Panels, to a File Editor

Read and you will find that with NetBeans Platform 7.1, associating new tabs to existing file editors will be easy and pluggable. I.e., you'll be able to create a new tab in one module and associate it with a file editor created in another module.

Right throughout NetBeans IDE this functionality will be used to provide a History tab for all files that you can edit in the IDE, e.g., here's a Java file and, as you can see, there's now two tabs, one named "Source", the other "History", which is very handy because the History tab records all the changes made in the Source tab:

So, how would you take your own file editor and add a History tab to it? As you can see from the link with which this blog entry started, each existing DataObject is being taken and extended to support this new functionality. And the extension code depends on various factors, e.g., whether editor support is provided or not by the module providing the DataObject. You can look at the list of changed files above and apply them to your own file editor.

Let's do so now for Jean-Marc Borer's ABNF file editor, which I introduced in this blog yesterday. All changes, in this particular scenario, apply to the AbnfDataObject only.  First of all, let's remove the file editor and replace it with a multiview editor, which is done in the constructor of the DataObject:

public AbnfDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {
    super(pf, loader);
    lookup = new ProxyLookup(getCookieSet().getLookup(), new AbstractLookup(content));
//        content.add((Node.Cookie) DataEditorSupport.create(this, getPrimaryEntry(), getCookieSet()));
    registerEditor("text/x-abnf", true);

The new line above uses the method call "registerEditor". From the javadoc, you call "registerEditor" from the constructor with the appropriate mime type, in this case "text/x-abnf". The system will make all the related capabilities available i.e., Openable, Editable, CloseCookie, EditorCookie, LineCookie, SaveAsCapable. Because "true" is passed in, we're going to have a multiview component.

Next, we implement "Callable<CloneableEditorSupport.Pane>" and add this block of code to the DataObject:

protected int associateLookup() {
    return 1;

public Pane call() {
    return (Pane) MultiViews.createCloneableMultiView("text/x-abnf", this);

@MultiViewElement.Registration(displayName = "#ABNF",
iconBase = "org/netbeans/modules/abnf/abnf_icon.png",
mimeType = "text/x-abnf",
persistenceType = TopComponent.PERSISTENCE_ONLY_OPENED,
preferredID = "Abc1",
position = 1000)
public static MultiViewEditorElement createEditor(Lookup lkp) {
    return new MultiViewEditorElement(lkp);

The "associateLookup" method, which is new, is pretty interesting. From the javadoc, it influences the behavior of the "getLookup()" method. Depending on the returned integer, you can get a different, better, and more modern  content
of the Lookup. If you return 0, you delegate to getNodeDelegate().getLookup(). If you return 1, you delegate to getCookieSet().getLookup(), while also putting the FileObject, DataObject, and the Node into the Lookup. The general suggestion is to always return the highest supported version when creating new objects and to stick with a certain version when backward compatibility is needed.

Aside from that, the code above creates a new pane for the source view, which is registered in the central registry via an annotation. And, because the source view is registered as a tab in a multiview component, i.e., via the annotation, you will now automatically get a History tab. You will also be able to add additional components, e.g., JPanels, as tabs in your multiview component.

In this way, not only do you get a free History tab for your file editor, but also the start of a multiview component for editing your files, in this case, ABNF files:


Post a Comment:
  • HTML Syntax: NOT allowed

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.


« July 2016