<!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>
        <!-- -*- xhtml -*- -->
        <title>Writing POV-Ray Support for NetBeans III&#8212;Implementing a Project Type</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 III&#8212;Implementing a custom project type"/>
        <!--      Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. -->
        <!--     Use is subject to license terms.-->
    </head>
    <body>

        <h1>Writing POV-Ray Support for NetBeans III&#8212;Implementing a Project Type</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>
            and <a href="nbm-povray-2.html">second</a> parts of this tutorial, you may
            want to start there.</p>

        <h2 class="tutorial"><a name="setup"></a>Setting Up Dependencies</h2>

        <p>There are a few APIs which we will need to use classes from&#8212;so before
            starting to code, let's add dependencies from the Povray Projects module
            to those:</p>

        <div class="indent">

            <ol>

                <li><p>The Project APIs are not part of the NetBeans Platform, but of
                        NetBeans IDE. The NetBeans Platform Application template we used,
                        at the start of part 1, only included modules into our application
                        from the NetBeans Platform. Therefore, to start with, we need to
                        include the Project APIs into our application, before we can set
                        dependencies on them in our modules.</p>
                    <p>Right-click the <tt>povsuite</tt> application, choose Properties, and
                        then select the Libraries tab. In the Libraries tab, expand the
                        "ide" node, and select Project API, Project UI, and Project UI API,
                        as shown below:</p>
                    <p><img alt="" src="../../images/tutorials/povray/71/ch3/pic0.png"/></p>
                    <p>Finally, click the Resolve button, which includes a number of
                        additional modules into your application.</p>
                    <p>Click OK above.</p>

                </li>

                <li><p>Right-click the <tt>povsuite</tt> project and choose Run. The
                        application starts up. Now that it includes several project-related
                        modules, you should see a number of new features, accessed from
                        many new menu items, as shown below:</p>
                    <p><img alt="" src="../../images/tutorials/povray/71/ch3/pic2.png"/></p>

                    <p>Now we're going to extend the project functionality to
                        include support for a new project type for PovRay projects. That
                        means we'll need to use several APIs, on which we need to
                        set dependencies in the Povray Projects module.</p>
                </li>

                <li><p>Right-click the Povray Projects module in the Projects window in the IDE
                        package, and choose Properties from the popup menu. Open
                        the Libraries tab of the dialog:</p>
                    <p><img alt="" src="../../images/tutorials/povray/71/ch3/pic1.png"/></p>
                </li>

                <li>On the Libraries page of the project properties dialog, shown above, click the
                    Add Dependency button.</li>

                <li><p>In the dialog that appears, type "ProjectFactory".  The
                        Projects API module should become selected in the list below&#8212;it is
                        the module that provides this class, so we need a dependency on it to
                        be able to use the class.</p>
                    <p><img alt="" src="../../images/tutorials/povray/71/ch3/pic3.png"/></p>
                    <p>Press Enter or Click OK, and then either press Tab and then Space,
                        or click the Add Dependency button to add another dependency.</p></li>

                <li><p>Repeat the steps above with the following classes:</p>

                    <ul>

                        <li>In the add dependency dialog, type "FileObject".  When
                            "FileSystems API" becomes selected, press Enter or click OK.</li>

                        <li>Repeat these steps again, typing the name "Lookup", and
                            adding a dependency on the Lookup API.</li>

                        <li>Repeat these steps yet again, typing the name "AbstractNode", and
                            adding a dependency on the Nodes API.</li>

                        <li>Repeat these steps once again, typing the name "DataFolder", and
                            adding a dependency on the Loaders API.</li>

                        <li>Repeat these steps once more, typing the name "LogicalViewProvider", and
                            adding a dependency on the Project UI API.</li>

                        <li>Repeat these steps once more, typing the name "HelpCtx", and
                            adding a dependency on the Utilities API.</li>

                    </ul>
                </li>
                <li><p>You should now see the following:</p>
                    <p><img alt="" src="../../images/tutorials/povray/71/ch3/pic4.png"/></p>
                    <p>Click OK to dismiss the dialog. The Libraries node of the project should now show you
                        the dependencies you have set:</p>
                    <p><img alt="" src="../../images/tutorials/povray/71/ch3/pic5.png"/></p>
                </li>

            </ol>

        </div>

        <h2>Creating the Project Factory</h2>

        <p>As with <code>DataObjects</code> and <code>DataLoaders</code>, the system
            keeps a registry of things that can identify a directory as being a project
            and creates a <code>Project</code> object to represent it.  So, the first step
            in creating a our own project type is to create a factory&#8212;an implementation of
            <code>ProjectFactory</code> from the Projects API&#8212;which can figure
            out if a directory is a POV-Ray project and, if it is one, make an instance of our
            <code>Project</code> implementation for it.</p>

        <div class="indent">

            <ol>

                <li><p>Right-click the <code>org.netbeans.examples.modules.povproject</code>
                        package, and choose New &gt; Java Class:</p>
                    <p><img alt="" src="../../images/tutorials/povray/71/ch3/pic6.png"/></p>
                </li>

                <li>In the New File wizard that appears, enter the name
                    <tt>PovProjectFactory</tt>. Press Enter or click OK to create the new file.</li>

                <li>In the code editor, modify the class signature of <tt>PovProjectFactory</tt>
                    as follows:
                    <pre class="examplecode">public class PovProjectFactory implements ProjectFactory {</pre>
                    <p>Press Alt-Shift-F (Ctrl-Shift-F on Macintosh) to Fix Imports.</p></li>

                <li><p>Position the caret somewhere in the class signature line.  When the
                        lightbulb glyph appears in the margin, press Alt-Enter, and then Enter
                        again to accept the hint "Implement All Abstract Methods". The class
                        definition should now be as follows:</p>

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

import java.io.IOException;
import org.netbeans.api.project.Project;
import org.netbeans.spi.project.ProjectFactory;
import org.netbeans.spi.project.ProjectState;
import org.openide.filesystems.FileObject;

public class PovProjectFactory implements ProjectFactory {

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

    @Override
    public Project loadProject(FileObject projectDirectory, ProjectState state) throws IOException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void saveProject(Project project) throws IOException, ClassCastException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

}</pre>


                </li>

                <li>Add the following constants to the head of the <code>PovProjectFactory</code>
                    class definition, as follows:

                    <pre class="examplecode">public class PovProjectFactory implements ProjectFactory {

    <b>public static final String PROJECT_DIR = "pvproject";
    public static final String PROJECT_PROPFILE = "project.properties";</b></pre>

                </li>

                <li>

                    <p>The first method we will implement is the <code>isProject()</code>
                        method.  This method needs to be very fast&#8212;it should determine whether
                        or not a directory is a project as quickly as possible, because it will
                        be called once for each directory shown in the file chooser when the
                        user selects File &gt; Open Project.</p>

                    <p>
                        Implement the method as follows:</p>

                    <pre class="examplecode">@Override
public boolean isProject(FileObject projectDirectory) {
    <b>return projectDirectory.getFileObject(PROJECT_DIR) != null;</b>
}</pre>

                    <p>This simple test for the presence of a subdirectory called
                        "pvproject" is all we need to determine that something is
                        <i>not</i> one of our projects.</p>

                </li>

                <li>

                    <p>Next, we will implement the code that actually loads a project, given a
                        directory.  The project system handles caching of projects, so all that's
                        needed here is to create a new project:</p>

                    <pre class="examplecode">@Override
public Project loadProject(FileObject projectDirectory, ProjectState state) throws IOException {
    <b>return isProject (projectDirectory) ? new PovrayProject (projectDirectory, state) : null;</b>
}</pre>

                    <p>The only interesting thing here is the <code>ProjectState</code> object, which
                        we pass along with the directory to our project's constructor.  It is provided
                        to us by the project system, and can be used to mark a project as needing to
                        be saved.  We will use it later to do that when the user changes the main file
                        of the project, which will be written to disk in the <code>project.properties</code>
                        when our project is closed.</p>

                </li>

                <li>
                    <p>The final thing to implement is <code>saveProject()</code>&#8212;this is what will
                        write out any unsaved changes to disk when a POV-Ray project is closed, or
                        when the application shuts down:</p>

                    <pre class="examplecode">@Override
public void saveProject(Project project) throws IOException, ClassCastException {

    FileObject projectRoot = project.getProjectDirectory();
    if (projectRoot.getFileObject(PROJECT_DIR) == null) {
        throw new IOException ("Project dir " + projectRoot.getPath() + " deleted," +
                " cannot save project");
    }

    //Force creation of the scenes/ dir if it was deleted
    project.getLookup(PovrayProject.class).getScenesFolder(true);

    //Find the properties file pvproject/project.properties,
    //creating it if necessary
    String propsPath = PROJECT_DIR + "/" + PROJECT_PROPFILE;
    FileObject propertiesFile = projectRoot.getFileObject(propsPath);
    if (propertiesFile == null) {
        //Recreate the properties file if needed
        propertiesFile = projectRoot.createData(propsPath);
    }

    Properties properties = (Properties) project.getLookup().lookup (Properties.class);
    File f = FileUtil.toFile(propertiesFile);
    properties.store(new FileOutputStream(f), "NetBeans Povray Project Properties");

}</pre>

                </li>
            </ol>

        </div>

        <p>We haven't written the <code>PovrayProject</code> yet, which is why you have
            some red underline error marks in your code, but from this code it's pretty clear
            what it will look like&#8212;we are creating the <code>scenes/</code> directory if it
            does not exist or was deleted;  we fetch a Properties object out of the project's
            <code>Lookup</code>, and save it into <code>pvproject/project.properties</code>&#8212;that's
            all there is or will be to saving a POV-Ray project.</p>

        <h2 class="tutorial"><a name="implementing"></a>Implementing PovrayProject</h2>

        <p>Now we need to create the Java class that represents a POV-Ray project&#8212;this is
            what our <code>PovProjectFactory</code> will create if the user opens a project
            that it owns.  The Project API in NetBeans is quite simple.  A "project",
            programmatically is the association of a directory on disk with a <code>Lookup</code> -
            a bag-o-stuff that can be queried for known interfaces.  The Project API then
            defines some interfaces and classes that should be available from a <code>Project</code>'s
            Lookup.</p>

        <p>So the first thing will be to create our implementation of
            <code>org.netbeans.api.project.Project</code>.</p>

        <div class="indent">

            <ol>

                <li>Right-click the <code>org.netbeans.examples.modules.povproject</code>
                    package in the Povray Projects project, and choose New &gt; Java Class again.
                    In the New File wizard that appears, enter the name
                    <tt>PovrayProject</tt>. Press Enter or click OK to create the new file.</li>

                <li><p>In the code editor, modify the signature line of <code>PovrayProject</code>
                        as follows:</p>
                    <pre class="examplecode">public final class PovrayProject implements Project {</pre>
                    <p>Press Alt-Shift-F (Ctrl-Shift-F on Macintosh) to Fix Imports.</p></li>

                <li>Position the caret somewhere in the class signature line.  When the
                    lightbulb glyph appears in the margin, press Alt-Enter, and then Enter
                    again to accept the hint "Implement All Abstract Methods". You should
                    now see the following:
                    <pre class="examplecode">package org.netbeans.examples.modules.povproject;

import org.netbeans.api.project.Project;
import org.openide.filesystems.FileObject;
import org.openide.util.Lookup;

public class PovrayProject implements Project {

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

    @Override
    public Lookup getLookup() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

}</pre>

                </li>

                <li>Implement the top of the class as follows:
                    <pre class="examplecode">public class PovrayProject implements Project {

    public static final String SCENES_DIR = "scenes"; //NOI18N
    public static final String IMAGES_DIR = "images"; //NOI18N

    private final FileObject projectDir;
    LogicalViewProvider logicalView = new PovrayLogicalView(this);
    private final ProjectState state;

    public PovrayProject(FileObject projectDir, ProjectState state) {
        this.projectDir = projectDir;
        this.state = state;
    }

    @Override
    public FileObject getProjectDirectory() {
        return projectDir;
    }

    FileObject getScenesFolder(boolean create) {
        FileObject result =
            projectDir.getFileObject(SCENES_DIR);

        if (result == null && create) {
            try {
                result = projectDir.createFolder (SCENES_DIR);
            } catch (IOException ioe) {
                Exceptions.printStackTrace(ioe);
            }
        }
        return result;
    }

    FileObject getImagesFolder(boolean create) {
        FileObject result =
            projectDir.getFileObject(IMAGES_DIR);
        if (result == null && create) {
            try {
                result = projectDir.createFolder (IMAGES_DIR);
            } catch (IOException ioe) {
                Exceptions.printStackTrace(ioe);
            }
        }
        return result;
    }
                    </pre>
                    <p>The last two methods we will use later on in this tutorial&#8212;they define (and can create) the
                        <code>scenes</code> code and <code>images</code> folders that POV-Ray source
                        files and their resulting image files will go into when the project is
                        rendered.</p>

                </li>

                <li><p>The actually interesting code goes into our implementation of <code>getLookup()</code>.
                        Eventually we will put some of our own interfaces into the project's <code>Lookup</code>;
                        for now it will be mainly standard stuff&#8212;interfaces provided by the Project API
                        module which we will implement.  Implement <code>getLookup()</code> as follows:</p>

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

    @Override
    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
                    });
        }
        return lkp;
    }</pre>

                </li>

                <li><p>The one interesting thing in the code above
                        is the call to <code>loadProperties()</code>&#8212;for
                        storing project settings, we will use a properties file.  So all we do here
                        is read it into a <code>Properties</code> object, and make that object available
                        through the project's <code>Lookup</code>.  We will want to save any changes
                        made to this properties object, so we'll use a bit of cleverness and create
                        a <code>Properties</code> subclass that will mark the project as needing
                        saving whenever something calls <code>put()</code>:</p>

                    <pre class="examplecode">    private Properties loadProperties() {

        FileObject fob = projectDir.getFileObject(PovProjectFactory.PROJECT_DIR
                + "/" + PovProjectFactory.PROJECT_PROPFILE);

        Properties properties = new NotifyProperties(state);
        if (fob != null) {
            try {
                properties.load(fob.getInputStream());
            } catch (Exception e) {
                Exceptions.printStackTrace(e);
            }
        }

        return properties;

    }

    private static class NotifyProperties extends Properties {

        private final ProjectState state;

        NotifyProperties(ProjectState state) {
            this.state = state;
        }

        @Override
        public Object put(Object key, Object val) {

            Object result = super.put(key, val);

            if (((result == null) != (val == null)) || (result != null
                    && val != null && !val.equals(result))) {
                state.markModified();
            }

            return result;

        }

    }</pre>

                    <p>Other than that, the things in the <code>Lookup</code> are what should typically be found
                        in the <code>Lookup</code> of any project&#8212;the project itself (the project
                        infrastructure reserves the right to wrap any Project type in a wrapper Project
                        object, so this guarantees being able to get at the real project instance),
                        its state, an <code>ActionProvider</code> to handle standard commands like
                        Build and Clean, a <code>ProjectInformation</code> implementation that
                        supplies the display name and icon for the project.  The last thing in the
                        lookup is the <i>logical view</i> which we will come to next&#8212;this is what
                        provides a <code>Node</code> for the project that will be displayed on the
                        <i>Projects</i> tab in NetBeans.</p>

                </li>

                <li>
                    <p>There are two remaining classes we need to create&#8212;the implementations of
                        <code>ActionProvider</code> and <code>ProjectInformation</code>.  We will simply
                        stub these for now&#8212;add these two classes as inner classes of <code>PovrayProject</code>:</p>

                    <pre class="examplecode">private final class ActionProviderImpl implements ActionProvider {

    @Override
    public String[] getSupportedActions() {
        return new String[0];
    }

    @Override
    public void invokeAction(String string, Lookup lookup) throws IllegalArgumentException {
        //do nothing
    }

    @Override
    public boolean isActionEnabled(String string, Lookup lookup) throws IllegalArgumentException {
        return false;
    }

}

/**
 * Implementation of project system's ProjectInformation class
 */
private final class Info implements ProjectInformation {

    @Override
    public Icon getIcon() {
        return new ImageIcon(ImageUtilities.loadImage(
                "org/netbeans/examples/modules/povrayproject/resources/scenes.gif"));
    }

    @Override
    public String getName() {
        return getProjectDirectory().getName();
    }

    @Override
    public String getDisplayName() {
        return getName();
    }

    @Override
    public void addPropertyChangeListener(PropertyChangeListener pcl) {
        //do nothing, won't change
    }

    @Override
    public void removePropertyChangeListener(PropertyChangeListener pcl) {
        //do nothing, won't change
    }

    @Override
    public Project getProject() {
        return PovrayProject.this;
    }

}</pre>

            </ol>

        </div>

        <h2 class="logical-view"><a name="implementing"></a>Implementing the Logical View</h2>

        <p>One line in the code you entered above should still be marked as being an error:</p>

        <pre class="examplecode">LogicalViewProvider logicalView = new PovrayLogicalView(this);</pre>

        <p>In NetBeans IDE, what you see in the Projects window is a "logical
            view" of your project.  This is a view that may not exactly reflect
            the structure of files on disk (the Files window and Favorites window is for that), but is more
            convenient to work with&#8212;for example, collapsing a tree of directories
            into a single node with a Java package name.</p>
        <p>
            What we will implement now is a <code>LogicalViewProvider</code>.  This is
            basically a factory that produces a <code>Node</code>
            that represents the project.  What child <code>Node</code>s that <code>Node</code>
            has, and what actions are available on them is up to us.
        </p>

        <div class="indent">

            <ol>

                <li>Right-click the <code>org.netbeans.examples.modules.povproject</code>
                    package in the Povray Projects project, and choose New &gt; Java Class.
                    In the New File wizard that appears, enter the name
                    "PovrayLogicalView". Press Enter or click OK to create the new file.</li>

                <li>In the code editor, modify the signature line of <code>PovrayLogicalView</code>
                    as follows:
                    <pre class="examplecode">class PovrayLogicalView implements LogicalViewProvider {</pre><p>
                        <p>Press Alt-Shift-F (Ctrl-Shift-F on Macintosh) to Fix Imports.</p></li>

                <li><p>Position the caret somewhere in the class signature line.  When the
                        lightbulb glyph appears in the margin, press Alt-Enter, and then Enter
                        again to accept the hint "Implement All Abstract Methods".</p>

                    <p>We now have a skeleton implementation of our logical view:</p>

                    <pre class="examplecode">class PovrayLogicalView implements LogicalViewProvider {

    public PovrayLogicalView(PovrayProject aThis) {
    }

    @Override
    public Node createLogicalView() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Node findPath(Node root, Object target) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

}</pre>

                    <p class="notes"><b>Note:</b> Part of the value of having a concept of a project is the ability to present
                        data in a way that is closer to the way a user will <i>think</i> about their
                        project than the structure of files on disk may be.  The logical view of a project
                        should present a simplified structure showing users what they need to
                        get their work done.</p>

                    <p class="notes"><b>Note:</b> In our case, we <a href="nbm-povray-2.html#phys">already decided</a> that
                        the user did not need to see the <code>images/</code> subdirectory, they should
                        just be able to click a scene file and choose <i>View</i>, and that we want
                        to put scene files in a <code>scenes/</code> subdirectory.  So the logical
                        thing to do for our logical view is to have it show the contents of that
                        <code>scenes/</code> directory.  We can return whatever <code>Node</code> we
                        want as the root of our logical view of the project, and NetBeans makes
                        using the content of the <code>scenes/</code> subdirectory very easy.</p>

                    <p class="tips">In the Nodes API is a class called <code>FilterNode</code>.  What it does is
                        wrap an existing <code>Node</code>, and by default, simply expose the same
                        child nodes, display name, icon, actions, etc. as the original.  We can
                        subclass <code>FilterNode</code> to change its icon and the set of actions
                        available on it.  The <code>DataLoader</code> infrastructure already provides
                        a loader that recognizes Filesystem folders&#8212;an API class called
                        <code>DataFolder</code>.  So we get the original node for the folder for free&#8212;we
			just need to provide a subclass that uses our icon and (eventually) actions.</p>
                </li>
                <li>We can now implement <code>PovrayLogicalView</code> as follows:
                    <pre class="examplecode">class PovrayLogicalView implements LogicalViewProvider {

    private final PovrayProject project;

    public PovrayLogicalView(PovrayProject project) {
        this.project = project;
    }

    @Override
    public Node createLogicalView() {

        try {

            //Get the scenes directory, creating if deleted:
            FileObject scenes = project.getScenesFolder(true);

            //Get the DataObject that represents it:
            DataFolder scenesDataObject =
                    DataFolder.findFolder(scenes);

            //Get its default node&#8212;we'll wrap our node around it to change the
            //display name, icon, etc:
            Node realScenesFolderNode = scenesDataObject.getNodeDelegate();

            //This FilterNode will be our project node:
            return new ScenesNode(realScenesFolderNode, project);

        } catch (DataObjectNotFoundException donfe) {

            Exceptions.printStackTrace(donfe);

            //Fallback&#8212;the directory couldn't be created -
            //read-only filesystem or something evil happened:
            return new AbstractNode (Children.LEAF);

        }

    }

    /**
     * This is the node you actually see in the Projects window for the project
     */
    private static final class ScenesNode extends FilterNode {

        final PovrayProject project;

        public ScenesNode(Node node, PovrayProject project) throws DataObjectNotFoundException {
            super(node, new FilterNode.Children(node),
                    //The projects system wants the project in the Node's lookup.
                    //NewAction and friends want the original Node's lookup.
                    //Make a merge of both:
                    new ProxyLookup(
                        Lookups.singleton(project),
                        node.getLookup())
                    );
            this.project = project;
        }

        @Override
        public Image getIcon(int type) {
            return ImageUtilities.loadImage(
                    "org/netbeans/examples/modules/povproject/resources/scenes.gif");
        }

        @Override
        public Image getOpenedIcon(int type) {
            return getIcon(type);
        }

        @Override
        public String getDisplayName() {
            return project.getProjectDirectory().getName();
        }

    }

    @Override
    public Node findPath(Node root, Object target) {
        //leave unimplemented for now
        return null;
    }

}</pre>

                    <p>The interesting code above is in the method <code>createLogicalView()</code>.
                        What we do there is quite simple and elegant&#8212;we have already decided that
                        there will be a <code>scenes/</code> directory in our project, and that's
                        where new <code>.pov</code> and <code>.inc</code> files will be created.
                        And that is all we want to expose to the user when they interact with one of
                        our projects.  So, we simply find the <code>Node</code> for that folder in
                        the real filesystem on disk, and wrap it in our own <code>FilterNode</code>,
                        which can expose whatever actions, icon, child <code>Node</code>s or
                        properties we choose.  Essentially, the logical view of the project is a
                        view of a subdirectory of the project, with a special icon and (eventually)
                        set of actions.</p>

                    <p>The final method, <code>findPath()</code> allows a user to use a keystroke to
                        select whatever they're editing in the <i>Projects</i> tab in the main window -
                        we will leave that unimplemented for now.</p>

                </li>

                <li><p>One final thing we need to do is to provide the icon referenced from
                        <code>PovrayLogicalView.ScenesNode.getIcon()</code> above.  Any 16x16 <code>.gif</code>
                        or <code>.png</code> file will do, or you can use <a href="../../images/tutorials/povray/scenes.gif">
                            this one <img src="../../images/tutorials/povray/scenes.gif" border="0"/></a>.  Create
                        a new java package "resources" underneath
                        <code>org.netbeans.examples.modules.povproject</code>, and copy or save the
                        image file there, modifying the file name in the source code if necesary.</p>
                </li>

            </ol>

        </div>

        <h2 class="tutorial"><a name="registering"></a>Registering the Project Factory</h2>

        <p>The system needs to know about our project type, for this module to do anything.
            We will register our project type into the default
            lookup using the technique of adding a file to <code>META-INF/services</code>
            in our module's JAR:</p>

        <div class="indent">

            <ol>

                <li>Add the @ServiceProvider annotation above the class signature
                    of the factory class:

                    <pre class="examplecode">@ServiceProvider(service=ProjectFactory.class)
public class PovProjectFactory implements ProjectFactory {</pre>
                </li>

                <li>Right-click the Povray Project and choose Build.</li>

                <li>In the Files window, expand the 'build' folder
                    and notice that the META-INF/services folder has
                    been created for you, via the build process, at which
                    time a NetBeans annotation processor processed
                    the @ServiceProvider annotation:
                    <p><img alt="" src="../../images/tutorials/povray/71/ch3/pic7.png"/></p>
                </li>
                <li><p>When you open the file above, notice that it consists of one
                        line, which is the name of the implementing class:</p>
                    <pre class="examplecode">org.netbeans.examples.modules.povproject.PovProjectFactory</pre>

            </ol>

        </div>

        <p>
            That's all it takes to register our project type, so that when our module is
            loaded, the NetBeans Platform will start recognizing POV-Ray projects.</p>


        <h2 class="logical-view"><a name="next"></a>Trying Out the New Project</h2>

        <p>We now have a working (albeit not terribly useful) implementation of POV-Ray
            projects.  As yet we have no way to create such a project on disk, but if you
            were to have one, you could open it and view it.</p>

        <div class="indent">

            <ol>

                <li>To try out your code at this point, download <a href="../../images/tutorials/povray/71/ch3/Wonderland.zip">Wonderland.zip</a> which contains such a project, unpack it to a temporary
                    directory and attempt to open it as a project, following the steps below.</li>

                <Li><p>Run the application, go to File | Open Project, and when you
                    browse to the temporary directory created above, you should
                    see that your project is recognized:</p>

                    <p><img alt="" src="../../images/tutorials/povray/71/ch3/pic8.png"/></p></li>

                <li><p>Open the project. In the Projects window, you will
                        see the logical view created above:</p>
                    <p><img alt="" src="../../images/tutorials/povray/71/ch3/pic9.png"/></p></li>

                <li><p>In the Files window, you will see all the files in the project:</p>

                    <p><img alt="" src="../../images/tutorials/povray/71/ch3/pic10.png"/></p>
                </li>

            </ol>

        </div>

        <h2 class="logical-view"><a name="next"></a>Next Steps</h2>

        <p>The <a href="nbm-povray-4.html">next tutorial</a> will begin to add truly
            useful functionality to our projects.</p>

    </body>

</html>
