Ruben Laguna's blog

Jul 22, 2009 - 4 minute read - api dot file graph graphbrowser graphviz guess java library netbeans open support visual

Adding support for opening dot files to GraphBrowser

I spent some time on GraphBrowser, starting off the project, the first step has been to add basic support for opeining Graphviz DOT files.

There are already some pages on the net talking about how to add open file support for new file types in NetBeans.

So there is no need to explain how to do it in a detailed way.

The first main step is to invoke New File Type wizard on the module (in my case MainModule) to add the basic files to support the file type.

  1. Navigate to the MainModules and click Add ⇒ New ⇒ File Type
  2. Fill the MIME-type for Graphviz DOT files which is `text/vnd.graphviz` and the filename extensions `.dot,.DOT`
  3. Click Next
  4. Class Name Prefix : DotFile
  5. Select a 16x16 icon file. You can create your own PNG icon file by using an icon creator/designer/editor/maker like IcoFX
  6. NetBeans will create a bunch of files for you and will also update layer.xml
    • Bundle.properties
    • DotFileDataObject.java
    • DotFileResolver.xml
    • DotFileTemplate.dot
    • dot.gif
Now that we have the basic support in place. The files generated by the New File Type wizard provide a default behaviour that consist on opening the file in a text editor, we don't want that so the next step is to do changes to DotFileDataObject.java. We must replace the DataEditorSupport.create with a custom OpenSupport.
public DotFileDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {
        super(pf, loader);
        CookieSet cookies = getCookieSet();
        //cookies.add((Node.Cookie) DataEditorSupport.create(this, getPrimaryEntry(), cookies));
        cookies.add(new DotFileOpenSupport(getPrimaryEntry()));
    }

And then we create a DotFileOpenSupport class that extends OpenSupport and implements Node.Cookie and OpenCookie

package com.rubenlaguna.graphbrowser.mainmodule;

import org.openide.cookies.OpenCookie;
import org.openide.loaders.MultiDataObject.Entry;
import org.openide.loaders.OpenSupport;
import org.openide.nodes.Node;
import org.openide.windows.CloneableTopComponent;

/**
 *
 * @author ECERULM
 */
class DotFileOpenSupport extends OpenSupport implements Node.Cookie, OpenCookie {

    public DotFileOpenSupport(Entry primaryEntry) {
        super(primaryEntry);

    }

    @Override
    protected CloneableTopComponent createCloneableTopComponent() {
        //throw new UnsupportedOperationException("Not supported yet.");
        GraphTopComponent tc = GraphTopComponent.findInstance();
        tc.setDisplayName(entry.getDataObject().getName());
        tc.setDotFile(entry);
        return tc;

    }
}

This newly created DotFileOpenSupport opens a TopComponent(GraphTopComponent), sets the display name of the TopComponent and load the file into the TopComponent.

So now we have to create GraphTopComponent. We can use the Window Component wizard. Just right click on the MainModule and New ⇒ Window Component. The wizard will do everything for us, the only information that we need to provide it’s specify the window position (editor) and class name prefix (Graph) and an icon. After clicking Finish, Netbeans generates a bunch of files and entries in layer.xml. We should open GraphTopComponent and change it to extend CloneableTopComponent instead of TopComponent as OpenSupport.createCloneableTopComponent() requires a CloneableTopComponent. We also need to add a setDotFile implementation. We will add it empty for now.

    void setDotFile(Entry entry) {
        //throw new UnsupportedOperationException("Not yet implemented");
    }

Now we can test our progress so far. 1

Double clicking on a dot file will open the GraphTopComponent and update the display name nothing more. It’s possible to review the changes did so far in kenai.

Now it’s time to add some real stuff to the GraphTopComponent. This means to to add some real logic to setDotFile and actually parse the dot file and create a visual representation of it using Netbeans Visual Library.

For parsing the DOT file we will use JPGD. We will wrap JPGD in a netbeans module to make thing easier.

So download JPGD 0.8.6beta and untar it. Then click on the project and click on Add new library. Then select “com.alexmerz.graphviz.jar” and “LICENSE”. Click next. You can the com.alexmerz.graphviz as project name. Code name base: com.alexmerz.graphviz and module display name leave also “com.alexmerz.graphviz”. Click Finish. Netbeans will create a Netbeans Library Wrapper module. To learn how to attach the source code to this newly created module follow the instructions on this post. Now the module is added to the project and we need to add a dependency in the MainModule to our newly created “com.alexmerz.graphviz” module so we can use it from MainModule. So right click on MainModule ⇒ Properties ⇒ Libraries ⇒ Add dependency ⇒ and select “com.alexmerz.graphviz”.

Now that we are handling the dependencies, we should add add a dependency to Visual Library API from MainModule. So first, we add a Visual Library API to the project. From the project properties, add dependency ⇒ platform 10 ⇒ Visual Library API. Then go to MainModule properties and add a dependency to Visual Library API too (Properties ⇒ Libraries ⇒ Visual Library API).

Now that we have the dependencies on place, we can add a JScrollPane to GraphTopComponent and a JPanel to the JScrollPanel. Then right-click on the JPanel and set the layout to BorderLayout.

Now it’s time to provide the implementation for GraphTopComponent.setDotFile:


    void setDotFile(Entry entry) {
        //throw new UnsupportedOperationException("Not yet implemented");



        this.scene = new DotGraphScene(entry);
        GraphLayout graphLayout = GraphLayoutFactory.createHierarchicalGraphLayout(scene, false);

        this.layout = LayoutFactory.createSceneGraphLayout(scene, graphLayout);
        Logger.getLogger(GraphTopComponent.class.getName()).info("invoking layout");
        layout.invokeLayoutImmediately();


        jPanel1.removeAll();
        JComponent view = scene.createView();
        jPanel1.add(view, BorderLayout.WEST);
        JComponent satelliteView = scene.createSatelliteView();
        jPanel1.add(satelliteView, BorderLayout.EAST);
        //scene.mainLayerToFront();
        //Logger.getLogger(GraphTopComponent.class.getName()).info("invoking paint");
        //scene.paint();
    }

We can test the application again. 2 Now the GraphTopComponent shows a graph representation of the GraphViz DOT file.

You can see the corresponding changes in mercurial by looking at these two changesets

The next step will be add dynamic layout and some of the layouts provided by GUESS.