<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

    <head>

        <title>Writing POV-Ray Support for NetBeans VIII&#8212;Implementing ViewService and its Actions</title>

        <link rel="stylesheet" type="text/css" href="https://netbeans.org/netbeans.css"/>
        <meta name="AUDIENCE" content="NBUSER"/>
        <meta name="TYPE" content="ARTICLE"/>
        <meta name="EXPIRES" content="N"/>
        <meta name="developer" content="geertjan.wielenga@oracle.com"/>
        <meta name="indexed" content="y"/>
        <meta name="description"
              content="NetBeans POV-Ray Support Tutorial Part VIII&#8212;Implementing the last part of our API and using it from file nodes"/>
        <!--      Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. -->
        <!--     Use is subject to license terms.-->

    </head>

    <body>

        <h1>Writing POV-Ray Support for NetBeans VIII&#8212;Implementing ViewService and its Actions</h1>

        <p>This is a continuation of the tutorial for building a POV-Ray rendering application on
            the NetBeans Platform. If you have not read the <a href="nbm-povray-1.html">first</a>,
            <a href="nbm-povray-2.html">second</a>, <a href="nbm-povray-3.html">third</a>,
            <a href="nbm-povray-4.html">fourth</a>, <a href="nbm-povray-5.html">fifth</a>,
            <a href="nbm-povray-6.html">sixth</a>, and <a href="nbm-povray-7.html">seventh</a>
            parts of this tutorial, you may want to start there.</p>

        <h2 class="tutorial"><a name="viewservice-impl"></a>ViewService&#8212;the Final API Piece</h2>

        <p>The last piece of our API to implement is <code>ViewService</code>, which will
            allow us to show the most recently rendered image file associated with a
            POV-Ray file.</p>

        <div class="indent">

            <ol>

                <li>Create a new Java class in
                    <code>org.netbeans.examples.modules.povproject</code>, called
                    &quot;ViewServiceImpl&quot;.</li>

                <li><p>We have one utility method we created earlier, for stripping the
                        extension from a file name.  We might as well reuse it here, since here
                        we will also need to compute the image name given a scene file.  So
                        open the <code>Povray</code> class in the editor, and modify
                        the signature of <code>stripExtension()</code> as follows, so that
                        it is changed from <tt>private</tt> to <tt>public static</tt>:</p>

                    <pre class="examplecode"><b>public static</b> String stripExtension(File f) {</pre>

                </li>

                <li><p>Returning to <code>ViewServiceImpl</code>, implement <tt>ViewService</tt>
                        and invoke Fix Imports and use the
                        &quot;Implement All Abstract Methods&quot; hint to provide skeleton
                        implementations of all of the methods:</p>

                    <pre class="examplecode">package org.netbeans.examples.modules.povproject;

import org.netbeans.examples.api.povray.ViewService;
import org.openide.filesystems.FileObject;

public class ViewServiceImpl implements ViewService {

    @Override
    public boolean isRendered(FileObject file) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean isUpToDate(FileObject file) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void view(FileObject file) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

}</pre>

                </li>

                <li><p>Now, add the following method to actually find the image file
                        for a given scene file:</p>

                    <pre class="examplecode">private FileObject getImageFor (FileObject scene) {
    FileObject imagesDir = proj.getImagesFolder(false);
    FileObject result;
    if (imagesDir != null) {
        File sceneFile = FileUtil.toFile (scene);
        if (sceneFile != null) {
            String imageName = Povray.stripExtension(sceneFile) + ".png";
            //Will be null if it doesn't exist:
            result = imagesDir.getFileObject (imageName);
        } else {
            result = null;
        }
    } else {
        //No images dir, there can't be an image
        result = null;
    }
    return result;
}</pre>

                </li>

                <li><p>Implement the constructor and API methods as follows:</p>

                    <pre class="examplecode">private final PovrayProject proj;

public ViewServiceImpl(PovrayProject proj) {
    this.proj = proj;
}

@Override
public boolean isRendered(FileObject file) {
    return getImageFor (file) != null;
}

@Override
public boolean isUpToDate(FileObject scene) {
    FileObject image = getImageFor (scene);
    boolean result;
    if (image != null) {
        result = scene.lastModified().before(image.lastModified());
    } else {
        result = false;
    }
    return result;
}

@Override
public void view(FileObject scene) {
    FileObject image = getImageFor(scene);
    if (image != null) {
        DataObject dob;
        try {
            dob = DataObject.find(image);
            OpenCookie open = dob.getNodeDelegate().getLookup().lookup(OpenCookie.class);
            if (open != null) {
                open.open();
                return;
            }
        } catch (DataObjectNotFoundException ex) {
            Exceptions.printStackTrace(ex);
        }
    }
    Toolkit.getDefaultToolkit().beep();
}</pre>

                </li>

                <li><p>Now we just need to expose our implementation of <code>ViewService</code>
                        via the project's lookup.  Modify <code>PovrayProject.getLookup()</code>
                        as follows:</p>

                    <pre class="examplecode">private Lookup lkp;

public Lookup getLookup() {
    if (lkp == null) {
        lkp = Lookups.fixed(new Object[] {
            this,  //handy to expose a project in its own lookup
            state, //allow outside code to mark the project as needing saving
            new ActionProviderImpl(), //Provides standard actions like Build and Clean
            loadProperties(), //The project properties
            new Info(), //Project information implementation
            logicalView, //Logical view of project implementation
            new RendererServiceImpl(this), //Renderer Service Implementation
            new MainFileProviderImpl(this), //So things can set the main file
            <b>new ViewServiceImpl(this), //Allow things to find/open the image associated with a scene file</b>
        });
    }
    return lkp;
}</pre>
                    <p class="tips"> The trailing comma in the array definition is not strictly necessary,
                        but it's a useful technique for reducing the CVS diff if you're using
                        version control, and so not a bad habit to have&#8212;if you add to the
                        array, you only change the lines you added.</p>
                </li>

            </ol>

        </div>

        <h2 class="tutorial"><a name="view-action"></a>Adding a View action to POV-Ray File Nodes</h2>

        <p>Now of course, we have implemented the API, but there is no code that uses it.
            So what we will do here is to add a &quot;View&quot; action to our POV-Ray file
            nodes.</p>

        <div class="indent">

            <ol>

                <li>In the Povray File Support project, open <code>PovRayDataNode</code>
                    in the <code>org.netbeans.examples.modules.povfile</code> package.</li>

                <li><p>First, we will add one more action into the array of popup menu
                        actions from <code>PovrayDataNode</code> (modified and new lines in
                        <b>bold</b>):</p>

                    <pre class="examplecode">public Action[] getActions (boolean popup) {
    Action[] actions = super.getActions(popup);
    RendererService renderer =
        (RendererService)getFromProject (RendererService.class);
    Action[] result;
    if (renderer != null && actions.length &gt; 0) { //should always be &gt; 0
        Action rendererAction = new RendererAction (renderer, this);
        <b>result = new Action[ actions.length + 3 ];</b>
        result[0] = actions[0];
        result[1] = new SetMainFileAction();
        result[2] = rendererAction;
        <b>result[3] = new ViewAction();</b>
    } else {
        //Isolated file in the favorites window or something
        result = actions;
    }
    return result;
}</pre>

                </li>

                <li><p>Now we need to implement ViewAction.  This can be an inner
                        class inside <code>PovrayDataNode</code>:</p>

                    <pre class="examplecode">@NbBundle.Messages("LBL_View=View")
private class ViewAction extends AbstractAction {

    ViewAction() {
        putValue(Action.NAME, Bundle.LBL_View());
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        ViewService service = (ViewService) getFromProject(ViewService.class);
        FileObject fob = getDataObject().getPrimaryFile();
        service.view(fob);
    }

    @Override
    public boolean isEnabled() {
        return getFromProject(ViewService.class) != null;
    }

}</pre>

                </li>

            </ol>

        </div>

        <p><p>At this point, we are ready to run the code.  Note that POV-Ray files now
                have a working View menu item:</p>
            <p><img alt="" src="../images/tutorials/povray/71/ch8/pic1.png"/></p>

        </p>

        <h2 class="icon-badging"><a name="next"></a>Icon-Badging&#8212;Adding File Listening Support</h2>

        <p>You may have noticed that there are a few methods we are not using on
            <code>ViewService</code>, particularly <code>isUpToDate()</code>.  In the
            NetBeans IDE, the icon for Java classes has a &quot;badge&quot; in the lower
            right if the compiled version of it is older than the source file and it
            probably needs recompilation.</p>

        <p>In an ideal world, we would parse POV-Ray source files, find all off their
            include files, and be able to tell if a rendered image is out of date based
            on all of that information.  However, that would be a bit out of scope for
            this tutorial, since we have no POV-Ray file parser at the moment.  What we
            can do easily enough, though, is use the implementation we already have of
            <code>isUpToDate()</code> and mark the <code>PovrayDataNode</code> icon
            if it is false.</p>

        <p>To do this, we will need to add a method to <code>RendererService</code>
            that lets an object listen for events, which should be fired when the
            rendered state of a file changes.  And this is exactly the sort of case where
            it is fortunate that <code>RendererService</code> is an abstract class&#8212;we
            can add the methods into the base class, with little risk of breaking any
            existing code that uses it (in practice there is the remote possibility that
            some implementation of <code>RendererService</code> already has a final
            method with the same name and signature [in fact exactly this happened to
            NetBeans when <code>getCause()</code> was added to <code>Throwable</code>
            in JDK 1.3], but it is a reasonable change).  In this case, of course, we
            know we are the only ones implementing <code>RendererService</code>, but if
            this feature were something we were adding after a release, there would be
            no way to be sure we wouldn't break existing clients by adding abstract
            methods.</p>

        <div class="indent">

            <ol>

                <li>Open <code>RendererService</code>, in the Povray API project's
                    <code>org.netbeans.modules.examples.api.povray</code> package, in the
                    code editor.</li>

                <li><p>Add the following field and methods.  What this will do is let a listener
                        register for change events against a specific scene file, and provide
                        a method that subclasses may call to fire such changes, and two methods
                        that can be overridden to do any additional work needed when a listener
                        is added or disappears.  Note that since our <code>PovrayDataNodes</code>
                        are created by the system on demand, they do not have such a well-defined
                        lifecycle.  So rather than try to find a point at which we can unregister
                        the listener, we will keep weak references to our listeners, so they can
                        be disposed as need-be.</p>

                    <pre class="examplecode">private Map scenes2listeners = new HashMap();

public final void addChangeListener(FileObject scene, ChangeListener l) {

    //Get the string name of the scene file—there is no need to hold
    //the FileObject itself in memory forever, we can let it be garbage
    //collected, and just hold the string path, which is less expensive
    String scenePath = scene.getName();

    //Make sure what we're doing is thread safe
    synchronized (scenes2listeners) {

        //We will use a weak reference to listeners, rather than have a
        //remove listener method.  This will allow our nodes to be garbage
        //collected if they are hidden
        Reference listenerRef = new WeakReference(l);
        List listeners = (List) scenes2listeners.get(scenePath);
        if (listeners == null) {
            listeners = new LinkedList();
            //Map the listener list for this path to the path
            scenes2listeners.put(scenePath, listeners);
        }

        //Add the weak reference to the list of listeners interested in
        //this scene
        listeners.add(listenerRef);

    }

    //Call our callback method—probably the implementation will start
    //listening to deletions of the image file, because we will need to
    //fire those too.  Do this outside of the synchronized block—never
    //call foreign code under a lock
    listenerAdded(scene, l);
}

protected void listenerAdded(FileObject scene, ChangeListener l) {
    //do nothing, should be overridden.  Here we should start listening
    //for changes in the image file (particularly deletion)
}

protected void noLongerListeningTo(FileObject scene) {
    //detach any listeners for image files being created/destroyed here
}

/**
* Fire a change event to any listeners that care about changes for the
* passed scene file. If the scene file is null, fire changes to all
* listeners for all files.
*
* @param scene a POV-Ray scene or include file
*/
protected final void fireSceneChange(FileObject scene) {

    String scenePath = scene == null ? null : scene.getName();
    List fireTo = null;

    //Use the 3-state (null, false, true) nature of a Boolean to decide if
    //we have really stopped listening
    Boolean stillListening = null;

    synchronized (scenes2listeners) {

        //Get the list of paths -> weak references -> listeners for this
        //scene
        List listeners;
        if (scenePath != null) {
            listeners = (List) scenes2listeners.get(scenePath);
        } else {
            listeners = new ArrayList();
            for (Iterator i = scenes2listeners.keySet().iterator(); i.hasNext();) {
                String path = (String) i.next();
                List curr = (List) scenes2listeners.get(path);
                if (curr != null) {
                    listeners.addAll(curr);
                }
            }
        }
        if (listeners != null && !listeners.isEmpty()) {
            //Create a list to put the listeners we will fire to into
            fireTo = new ArrayList(3);
            for (Iterator i = listeners.iterator(); i.hasNext();) {
                Reference ref = (Reference) i.next();
                //Get the next change listener for this path
                ChangeListener l = (ChangeListener) ref.get();
                if (l != null) {
                    //Add it to the list if it still exists
                    fireTo.add(l);
                } else {
                    //If not, remove the dead reference
                    i.remove();
                }
            }
            //If there is nothing listening, remove the empty listener list
            //and stop paying attention to this path
            if (listeners.isEmpty()) {
                scenes2listeners.remove(scenePath);
                stillListening = Boolean.FALSE;
            } else {
                stillListening = Boolean.TRUE;
            }
        }
    }

    //Call the listener removal method outside the synch block.
    //StillListening will be null if we were never listening at all
    if (stillListening != null && Boolean.FALSE.equals(stillListening)) {
        noLongerListeningTo(scene);
    }

    //Again, fire changes outside the synch block since we
    //are calling foreign code
    if (fireTo != null) {
        for (Iterator i = fireTo.iterator(); i.hasNext();) {
            ChangeListener l = (ChangeListener) i.next();
            l.stateChanged(new ChangeEvent(this));
        }
    }

}</pre>
                    <p class="notes"> At this stage, the import statement block
                        at the top of the above class should be as follows:
                        <pre class="java">import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.openide.filesystems.FileObject;</pre>
                    </p>
                </li>

                <li><p>Next we need to implement the two protected methods we defined above,
                        in our implementation of <code>RendererService</code>.  In the
                        Povray File Support project, open
                        <code>RendererServiceImpl</code> in the code editor.</p></li>

                <li><p>Now, we will need to implement a listener interface on
                        <code>RendererServiceImpl</code>, so modify its signature as follows:</p>

                    <pre class="examplecode">final class RendererServiceImpl extends RendererService <b>implements FileChangeListener</b> {</pre>

                    <p class="tips">Use the editor hint to create skeleton implementations of the methods
                        of these interfaces.  The thing to note here is that, unlike <code>java.io.File</code>,
                        it is possible to listen for changes on <code>org.openide.filesystems.FileObject</code>,
                        either folders or files.</p>

                </li>

                <li>
                    <p>The API class, <code>RendererService</code>, knows nothing about how
                        image files map to scene files.  However, our implementation of it does
                        know how to find the corresponding image file to a scene file.  So we will
                        override those methods to listen for changes in the presence, absence or
                        timestamp of the image file that corresponds to a POV-Ray file.  This involves
                        a bit of boilerplate listener code and bookkeeping to decide when to start
                        and stop listening:</p>

                    <pre class="examplecode">//Keep a list of the paths we are currently listening to
private Set scenesListenedTo = new HashSet();
private boolean listeningToImagesFolder = false;

@Override
protected void listenerAdded(FileObject scene, ChangeListener l) {
    synchronized (this) {
        if (scenesListenedTo.add(scene.getPath())) {
            if (scenesListenedTo.size() == 1 || !listeningToImagesFolder) {
                //This is the first call, so we should start listening
                //on the images folder
                startListeningToImagesFolder();
            }
            listenTo(scene);
        }
    }
}

@Override
protected void noLongerListeningTo(FileObject scene) {
    synchronized (this) {
        scenesListenedTo.remove(scene.getPath());
    }
}

private void startListeningToImagesFolder() {
    FileObject imageFolder = proj.getImagesFolder(false);
    listeningToImagesFolder = imageFolder != null;
    if (listeningToImagesFolder) {
        listenTo(imageFolder);
    }
}

private void listenTo(FileObject file) {
    //Add ourselves as a weak listener to the file.  This way we can still
    //be garbage collected if the project is closed
    FileChangeListener stub = (FileChangeListener) WeakListeners.create(
            FileChangeListener.class, this, file);

    file.addFileChangeListener(stub);
}

@Override
public void fileFolderCreated(FileEvent fileEvent) {
    //Do nothing
}

@Override
public void fileDataCreated(FileEvent fileEvent) {
    FileObject created = fileEvent.getFile();
    fireSceneChange(created);
}

@Override
public void fileChanged(FileEvent fileEvent) {
    FileObject changed = fileEvent.getFile();
    fireSceneChange(changed);
}

@Override
public void fileDeleted(FileEvent fileEvent) {
    FileObject deleted = fileEvent.getFile();
    fireSceneChange(deleted);
    if (deleted.isFolder() && "images".equals(deleted.getNameExt())) {
        //The images folder was deleted, reset our listening flags
        fireSceneChange(null);
        listeningToImagesFolder = false;
    }
}

@Override
public void fileRenamed(FileRenameEvent fileRenameEvent) {
    //do nothing
}

@Override
public void fileAttributeChanged(FileAttributeEvent fileAttributeEvent) {
    //do nothing
}</pre>
                </li>

                <li><p>One last change we need to make is to the <code>render()</code> method in
                        the <tt>RenderServiceImpl</tt> class&#8212;it
                        is possible that the <code>images/</code> directory of the project was
                        simply not there&#8212;it can legally be deleted.  In that case, there will be
                        nothing to listen to.  The first time we render, it will be recreated if
                        necessary.  So we need to check if we were listening on the <code>images/</code> folder,
                        and if not, start now that it's created.  So, we need to modify the
                        implementation of <code>render()</code> slightly:</p>

                    <pre class="examplecode">@Override
public FileObject render(FileObject scene, Properties renderSettings) {
    Povray pov = new Povray(this, scene, renderSettings);
    <b>FileObject result;</b>
    try {
        result = pov.render();
        <b>if (!listeningToImagesFolder) {
            startListeningToImagesFolder();
        }</b>
    } catch (IOException ioe) {
        Exceptions.printStackTrace(ioe);
        <b>result = null;</b>
    }
    <b>return result;</b>
}
                    </pre></li>

            </ol>

        </div>

        <p class="notes"> One thing worth noting is our use of the <code>WeakListeners</code> utility
            class.  This can be used to generate a variant of any event listener which
            will only reference the actual listener weakly&#8212;so you can add a listener
            to a long-lived object (such as the Project or something held strongly by
            it), but the listener can still be garbage collected.  So, the
            <code>FileObject</code>s we listen to can outlive the <code>RendererServiceImpl</code>
            or the <code>Project</code> and not force them to be retained in memory
            simply because something wanted to listen to changes in a file or folder.</p>

        <h2 class="icon-badging"><a name="next"></a>Icon-Badging&#8212;Implementing Icon Badging</h2>

        <p>Now we need to actually display different icons depending on the rendered
            state of the scene file being represented.  The NetBeans Utilities API offers
            a handy method for merging multiple
            images together&#8212;<code>ImageUtilities.mergeImages()</code>.</p>

        <div class="indent">

            <ol>

                <li>In the Povray File support module,
                    edit the class declaration of <code>PovrayDataNode</code> so that it
                    implements <code>ChangeListener</code> and add the appropriate <code>stateChanged()</code>
                    method.</li>

                <li><p>Add the highlighted code below, in the constructor for <code>PovrayDataNode</code>:</p>

                    <pre class="examplecode">public PovrayDataNode(PovrayDataObject obj) {
    super(obj, Children.LEAF);
    <b>RendererService serv = (RendererService) getFromProject(RendererService.class);
    if (serv != null) {
        //Could be an isolated file outside of a project, in which
        //case there is no renderer service
        serv.addChangeListener (obj.getPrimaryFile(), this);
    }</b>
}</pre>

                </li>

                <li><p>The <code>stateChanged()</code> method can be implemented very simply:</p>

                    <pre class="examplecode">public void stateChanged(ChangeEvent changeEvent) {
    <b>fireIconChange();</b>
}</pre>
                </li>

                <li><p>Now we need to override <code>getIcon()</code> to return different
                        icons depending on the state of the <code>Node</code>:</p>

                    <pre class="examplecode">private static final String NEEDS_RENDER_BADGE_FILE =
        "org/netbeans/examples/modules/povfile/needsRenderBadge.png";
private static final String HAS_IMAGE_BADGE_FILE =
        "org/netbeans/examples/modules/povfile/hasImageBadge.png";
private static final String NO_IMAGE_BADGE_FILE =
        "org/netbeans/examples/modules/povfile/hasNoImageBadge.png";

@Override
public Image getIcon(int type) {
    Image result = super.getIcon(type);
    ViewService vs = (ViewService) getFromProject(ViewService.class);
    if (vs != null) {
        FileObject file = getFile();
        boolean hasRender = vs.isRendered(file);
        if (hasRender) {
            Image badge1 = ImageUtilities.loadImage(HAS_IMAGE_BADGE_FILE);
            result = ImageUtilities.mergeImages(result, badge1, 8, 8);
            boolean upToDate = vs.isUpToDate(file);
            if (!upToDate) {
                Image badge2 = ImageUtilities.loadImage(NEEDS_RENDER_BADGE_FILE);
                result = ImageUtilities.mergeImages(result, badge2, 8, 0);
            }
        } else {
            Image badge3 = ImageUtilities.loadImage(NO_IMAGE_BADGE_FILE);
            result = ImageUtilities.mergeImages(result, badge3, 8, 8);
        }
    }
    return result;
}</pre>

                    <p>Here we have defined a set of constants that are paths to icons, and
                        depending on the state, we will merge various ones with the base.  Each of
                        our badge images is 8x8 pixels, so it can neatly be placed in one of the
                        quadrants of our 16x16 icon.</p>

                </li>

                <li><p>Create the necessary image files in the
                        <code>org.netbeans.examples.modules.povfile</code> package&#8212;here are
                        the ones used in the tutorial:</p>

                    <ul>
                        <li><b>hasImageBadge.png</b> <img alt="" src="../images/tutorials/povray/hasImageBadge.png"/></li>
                        <li><b>hasNoImageBadge.png</b> <img alt="" src="../images/tutorials/povray/hasNoImageBadge.png"/></li>
                        <li><b>needsRenderBadge.png</b> <img alt="" src="../images/tutorials/povray/needsRenderBadge.png"/></li>
                    </ul>

                </li>

                <li><p>Run the application. Notice the icon badging, and the changes when you
                        render or remove rendered images:</p>
                    <p><img alt="" src="../images/tutorials/povray/71/ch8/pic2.png"/></p>
                </li>

            </ol>

        </div>

        <h2 class="tutorial"><a name="next"></a>Next Steps</h2>

        <p>We're almost done.  The <a href="nbm-povray-9.html">next step</a>
            will be adding project build support and putting some finishing
            touches on our UI and code.</p>

    </body>

</html>
