<!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 VII&#8212;Support For Running POV-Ray</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 VII&#8212;How to launch an external process and monitor its output in the output window"/>
        <!--      Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. -->
        <!--     Use is subject to license terms.-->

    </head>

    <body>

        <h1>Writing POV-Ray Support for NetBeans VII&#8212;Support For Running POV-Ray</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>, and
            <a href="nbm-povray-6.html">sixth</a>
            parts of this tutorial, you may want to start there.</p>

        <h2 class="tutorial"><a name="executing"></a>Obtaining POV-Ray</h2>

        <p>At this point, we're almost ready to run code, so it would be a good idea
            to download a copy of POV-Ray.  </p>
        <ul>
            <li>Official builds can be obtained from
                <a href="http://povray.org">povray.org</a>.
		<!--		but there is a caveat&#8212;the
				Windows version of POV-Ray is a GUI executable, which will want to open
				an editor rather than render your file to disk.  So Windows users should
				download an &quot;unofficial&quot; build such as
				<a href="http://www.imagico.de/files/povcyg_350c.zip">this one</a>, or create
				a command-line build using cygwin and gcc.-->
	    </li>
            <li>Macintosh users may find
                <a href="http://darwinports.opendarwin.org/">DarwinPorts</a> the easiest
                way&#8212;simply install DarwinPorts and then run
                <code>sudo port install povray</code>.</li>
            <li>Linux and other Unix users should be
                fine with the downloads available from <a href="http://povray.org">povray.org</a>,
                using <a href="http://povray.org/download/linux.php">these instructions</a>.
		Everything should work out of the box for these users, without any
		tweaks or post-install configurations. Make sure, however, that the
		POV-Ray launcher has the correct permissions, otherwise it will not
		execute. Run it from the command line to check that it executes.</li>
        </ul>

	<p class="notes"><b>Note:</b> For details on setting up POV-Ray, especially
	    for detailed instructions for Windows, <a href="nbm-povray-10.html#appendix">see the Appendix</a>.</p>

        <h2 class="tutorial"><a name="setup"></a>Executing POV-Ray and Displaying the Output</h2>

        <p>At this point, we are ready to write the code that will actually invoke the
            external POV-Ray executable, pass it the correct arguments and display its
            output.</p>

        <p>At the end of this part of the tutorial, you will have an application
            that looks like this (click to enlarge the image):</p>

        <p><a href="../images/tutorials/povray/71/ch7/pic1.png"><img alt="" src="../images/tutorials/povray/71/ch7/pic2.png"/></a></p>


        <p>POV-Ray has two kinds of output:  It will write out status and
            success failure on the command line, in a similar way to what a compiler
            does, and it will write out an image file on disk, which we will want to
            display.</p>

        <p>The first part is just being able to invoke the external executable.
            NetBeans has some API classes that can help with that.</p>

        <div class="indent">

            <ol>

                <li><p>Add the following constructor and fields to the <code>Povray</code>
                        class:</p>
                    <pre class="examplecode">    private final RendererServiceImpl renderService;
    private final FileObject toRender;
    private final Properties settings;

    Povray (RendererServiceImpl renderService, FileObject toRender, Properties settings) {
        this.renderService = renderService;
        this.toRender = toRender;
        this.settings = settings == null ? renderService.getRendererSettings(
                renderService.getPreferredRendererSettingsName()) : settings;
    }</pre>
                </li>

                <li><p>Next we will implement a method that will find the file to render.
                        We were passed a <code>FileObject</code>, but now we need an actual
                        <code>java.io.File</code> to get the path from, to pass on the command
                        line to POV-Ray.  There are two caveats:  1.  The file passed to the
                        constructor may be null&#8212;in that case we should find the main file of
                        the project and use that; and 2. It is conceivable that the file will
                        not exist on disk&#8212;NetBeans filesystems are virtual, after all, and
                        the file could exist in a remote FTP filesystem or such.  Since NetBeans
                        4.0, this is rather unlikely, but we should still test for this condition
                        (<code>FileUtil.toFile()</code> returns null).  So we will add a method
                        to <code>Povray</code> as follows:</p>

                    <pre class="examplecode">private File getFileToRender() throws IOException {
    FileObject render = toRender;
    if (render == null) {
        PovrayProject proj = renderService.getProject();
        MainFileProvider provider = (MainFileProvider)
            proj.getLookup().lookup (MainFileProvider.class);
        if (provider == null) {
            throw new IllegalStateException ("Main file provider missing");
        }
        render = provider.getMainFile();
        if (render == null) {
            ProjectInformation info = (ProjectInformation)
                    proj.getLookup().lookup(ProjectInformation.class);

            //XXX let the user choose
            throw new IOException (NbBundle.getMessage(Povray.class,
                    "MSG_NoMainFile", info.getDisplayName()));
        }
    }
    assert render != null;
    File result = FileUtil.toFile (render);
    if (result == null) {
            throw new IOException (NbBundle.getMessage(Povray.class,
                    "MSG_VirtualFile", render.getName()));
    }
    assert result.exists();
    assert result.isFile();
    return result;
}</pre>

                </li>

                <li><p>Next we need to assemble the command-line arguments that need to
                        be passed to POV-Ray.  These take the form of
                        <code>+[some character][somevalue]</code>, for example,
                        <code>+A0.9</code> sets the anti-aliasing parameter to 0.9 pixels.
                        So we need to iterate the <code>Properties</code> object passed to the
                        constructor and assemble from it a set of command line arguments:</p>

                    <pre class="examplecode">private String getCmdLineArgs(File includesDir) {
    StringBuilder cmdline = new StringBuilder();
    for (Iterator i=settings.keySet().iterator(); i.hasNext();) {
        String key = (String) i.next();
        String val = settings.getProperty(key);
        cmdline.append ('+');
        cmdline.append (key);
        cmdline.append (val);
        cmdline.append (' ');
    }
    cmdline.append ("+L");
    cmdline.append (includesDir.getPath());
    return cmdline.toString();
}</pre>

                </li>

                <li><p>Next we need to implement a couple of utility methods that the
                        rendering method will use:</p>

                    <pre class="examplecode">private File getImagesDir() {
    PovrayProject proj = renderService.getProject();
    FileObject fob = proj.getImagesFolder(true);
    File result = FileUtil.toFile(fob);
    assert result != null && result.exists();
    return result;
}

private String stripExtension(File f) {
    String sceneName = f.getName();
    int endIndex;
    if ((endIndex = sceneName.lastIndexOf('.')) != -1) {
        sceneName = sceneName.substring(0, endIndex);
    }
    return sceneName;
}</pre>

                    <p>Neither is terribly exciting&#8212;one gets the images directory from the
                        project as a <code>java.io.File</code>, and the other trims the file
                        extension off a file name (so we can create an image file with the same
                        name as the scene file).</p>

                </li>

                <li><p>The next method we will add is another utility method.  When we
                        render, we will want to show messages on the status bar that describe
                        what is happening&#8212;or what went wrong in the event of failure.  The
                        UI Utilities API contains a class called <code>StatusDisplayer</code>
                        that lets any code in NetBeans that wants to write to the status bar
                        (the actual implementation of <code>StatusDisplayer</code> is in the
                        windowing system implementations, <code>core/windows</code> in NetBeans
                        CVS).</p>

                    <p>Implement the following method, and then add a dependency on the
                        UI Utilities API module from the Povray Projects module:</p>

                    <pre class="examplecode">private void showMsg (String msg) {
    StatusDisplayer.getDefault().setStatusText(msg);
}</pre>

                </li>

                <li><p>At this point, we've added a bunch of status messages our code can
                        display, so it is time to add actual text for those messages to the
                        resource bundle.  Note that in a number of cases we call:</p>

                    <pre class="examplecode">NbBundle.getMessage(SomeClass.class, &quot;MSG_Something&quot;, <i><u>someStringArgument</u></i>);</pre>

                    <p>to fetch a localized string.  <code>NbBundle</code> supports embedding
                        arguments inside of a localized string&#8212;you can either use the above
                        method, or a variant that takes an array of arguments to embed.  So you
                        can define strings in a resource bundle using the syntax:</p>

                    <pre class="examplecode">Could not delete {0} because {1}</pre>

                    <p>and <code>{0}</code> and <code>{1}</code> will be replaced by arguments
                        passed to <code>getMessage()</code>.  This is extremely useful, as often
                        the order in which such strings occur in the result text will be different
                        in different human languages.</p>

                    <p>So let's go ahead and add the warning messages we need to
                        <code>Bundle.properties</code> in the same package as <code>PovrayProject</code>:
                        <pre class="examplecode">MSG_NoMainFile=Main scene file not set for {0}
MSG_VirtualFile=Not a file on disk: {0}
MSG_Rendering=Rendering {0}
MSG_NoPovrayExe=No POV-Ray executable, cannot render
MSG_NoPovrayInc=No POV-Ray includes dir, cannot render
MSG_Success=Rendered {0} successfully
MSG_Failure=Failed to render {0}
MSG_CantDelete=Could not delete {0}, it is locked or in use</pre>

                    </p></li>

                <li><p>Now we are almost ready to get down to the nitty-gritty of actually
                        invoking POV-Ray from NetBeans.  We will do this in the standard Java
                        way, using <code>Runtime.exec()</code> to start an external process.
                        We also will want to display the text output from the process as it
                        reports its progress, in the output window.  This means we will need a
                        way to write to the output window.  So we will add one more dependency
                        to Povray Projects&#8212;add a dependency on the IO API module (use the class
                        name <code>InputOutput</code> in the Add Dependency dialog).</p>
                </li>

                <li><p>Handling output from a process is tricky&#8212;we will actually have
                        three threads running to handle our process:</p>

                    <ul>
                        <li>The thread that invoked the process and is waiting for it to
                            terminate</li>
                        <li>A thread that is collecting output from the standard output of
                            the POV-Ray process and writing it to the output window</li>
                        <li>Another thread that is doing the same thing for the error output
                            of the POV-Ray process</li>
                    </ul>

                    <p>So we will need some kind of <code>Runnable</code> which will wait for
                        data from each output stream and route it to the output window in
                        NetBeans as it becomes available.  Writing to the output window is quite
                        easy&#8212;you get an <code>InputOutput</code> object from
                        <code>IOProvider.getDefault()</code> and then write to one of its streams&#8212;for
                        example:</p>

                    <pre class="examplecode">    InputOutput io = IOProvider.getDefault().getIO ("Hello", true);
    io.select();
    io.getOut().println ("Hello world");
    io.getErr().println ("This is the standard error output&#8212;it should be red");</pre>

                    <p>is all it takes to make the output window pop up and display some output.</p>

                    <p>So before we implement the code that will create the process, lets create
                        the runnable that will wait for output from the process and route it to
                        the output window&#8212;it will be a static nested class inside the
                        <code>Povray</code> class:</p>

                    <pre class="examplecode">    static class OutHandler implements Runnable {

        private Reader out;

        private OutputWriter writer;

        public OutHandler (Reader out, OutputWriter writer) {
            this.out = out;
            this.writer = writer;
        }

        @Override
        public void run() {
            while (true) {
                try {
                    while (!out.ready()) {
                        try {
                            Thread.currentThread().sleep(200);
                        } catch (InterruptedException e) {
                            close();
                            return;
                        }
                    }
                    if (!readOneBuffer() || Thread.currentThread().isInterrupted()) {
                        close();
                        return;
                    }
                } catch (IOException ioe) {
                    //Stream already closed, this is fine
                    return;
                }
            }
        }

        private boolean readOneBuffer() throws IOException {
            char[] cbuf = new char[255];
            int read;
            while ((read = out.read(cbuf)) != -1) {
                writer.write(cbuf, 0, read);
            }
            return read != -1;
        }

        private void close() {
            try {
                out.close();
            } catch (IOException ioe) {
                Exceptions.printStackTrace(ioe);
            } finally {
                writer.close();
            }
        }

    }</pre>

                </li>

                <li><p>Now we are ready to implement the <code>render()</code> method in the
                        <tt>Povray</tt> class, in the Povray Project module, that
                        will invoke <code>POV-Ray</code>.  This method should be never be invoked from
                        the event thread, because it would block the UI until POV-Ray is finished.
                        So the first thing we do is sanity check what thread we're running on.
                        Then we get the file we need to render, sanity checking that. Then we
                        call <code>getPovray()</code> which may open a file chooser to let the
                        user pick it, and similarly get the default include directory which we
                        will need to pass on the command line.  Then we get the directory where
                        we will put the output, assemble our output file name (we use PNG format
                        since NetBeans' Image module supports that).</p>
                    <p>Then we compute the command
                        line that should be passed to POV-Ray.  Then we call
                        <code>Runtime.exec()</code> with that argument, wire up the output window
                        to the output streams from the resulting process, and wait for the
                        process to exit.  Once it exits, we determine if it succeeded or failed,
                        show an appropriate message, and if it succeeded, return a
                        <code>FileObject</code> representing the file that was created.</p>

                    <pre class="examplecode">public FileObject render () throws IOException {

    if (EventQueue.isDispatchThread()) {
        throw new IllegalStateException ("Tried to run povray from the " +
                "event thread");
    }

    //Find the scene file pass to POV-Ray as a java.io.File
    File scene;
    try {
        scene = getFileToRender();
    } catch (IOException ioe) {
        showMsg (ioe.getMessage());
        return null;
    }

    //Get the POV-Ray executable
    File povray = getPovray();
    if (povray == null) {
        //The user cancelled the file chooser w/o selecting
        showMsg(NbBundle.getMessage(Povray.class, "MSG_NoPovrayExe"));
        return null;
    }

    //Get the include dir, if it isn't under povray's home dir
    File includesDir = getStandardIncludeDir(povray);
    if (includesDir == null) {
        //The user cancelled the file chooser w/o selecting
        showMsg (NbBundle.getMessage(Povray.class, "MSG_NoPovrayInc"));
        return null;
    }

    //Find the image output directory for the project
    File imagesDir = getImagesDir();

    //Assemble and format the line switches for the POV-Ray process based
    //on the contents of the Properties object
    String args = getCmdLineArgs(includesDir);
    String outFileName = stripExtension (scene) + ".png";

    //Compute the name of the output image file
    File outFile = new File(imagesDir.getPath() + File.separator +
            outFileName);

    //Delete the image if it exists, so that any current tab viewing the file is
    //closed and the file will definitely be re-read when it is re-opened
    if (outFile.exists() && !outFile.delete()) {
        showMsg (NbBundle.getMessage(Povray.class,
                "LBL_CantDelete", outFile.getName()));
        return null;
    }

    //Append the input file and output file arguments to the command line
    String cmdline = povray.getPath() + ' ' + args + " +I" +
            scene.getPath() + " +O" + outFile.getPath();

    System.err.println(cmdline);

    showMsg (NbBundle.getMessage(Povray.class, "MSG_Rendering",
            scene.getName()));
    final Process process = Runtime.getRuntime().exec (cmdline);

    //Get the standard out of the process
    InputStream out = new BufferedInputStream (process.getInputStream(), 8192);

    //Get the standard in of the process
    InputStream err = new BufferedInputStream (process.getErrorStream(), 8192);

    //Create readers for each
    final Reader outReader = new BufferedReader (new InputStreamReader (out));
    final Reader errReader = new BufferedReader (new InputStreamReader (err));

    //Get an InputOutput to write to the output window
    InputOutput io = IOProvider.getDefault().getIO(scene.getName(), false);

    //Force it to open the output window/activate our tab
    io.select();

    //Print the command line we're calling for debug purposes
    io.getOut().println(cmdline);

    //Create runnables to poll each output stream
    OutHandler processSystemOut = new OutHandler (outReader, io.getOut());
    OutHandler processSystemErr = new OutHandler (errReader, io.getErr());

    //Get two different threads listening on the output & err
    //using the system-wide thread pool
    RequestProcessor.getDefault().post(processSystemOut);
    RequestProcessor.getDefault().post(processSystemErr);

    try {
        //Hang this thread until the process exits
        process.waitFor();
    } catch (InterruptedException ex) {
        Exceptions.printStackTrace(ex);
    }

    //Close the output window's streams (title will become non-bold)
    processSystemOut.close();
    processSystemErr.close();

    if (outFile.exists() && process.exitValue() == 0) {
        //Try to find the new image file
        FileObject outFileObject = FileUtil.toFileObject(outFile);
        showMsg (NbBundle.getMessage(Povray.class, "MSG_Success",
            outFile.getPath()));
        return outFileObject;
    } else {
        showMsg (NbBundle.getMessage(Povray.class, "MSG_Failure",
            scene.getPath()));
        return null;
    }

}</pre>

                </li>

                <li><p>The last thing is to fix our implementation of
                        <code>RendererService</code> to call <code>Povray.render()</code>.
                        Open <code>RendererServiceImpl</code> in the code editor, and modify
                        the render method:</p>

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

                </li>

                <li><p>The last step is to open the image when the rendering process is
                        complete.  This is quite simple to implement&#8212;we just need to look
                        for an <code>OpenCookie</code> on the <code>Node</code> for the image
                        that was rendered.  If you are running a standard configuration of the
                        NetBeans IDE, you already have the Image module installed&#8212;it will
                        provide support for opening an image, displaying it in the editor area.
                        So implement <code>RendererAction.RenderWithSettingsAction.run()</code> like
                        this:</p>

                    <pre class="examplecode">public void run() {
    DataObject ob = node.getDataObject();
    FileObject toRender = ob.getPrimaryFile();
    <b>Properties mySettings = renderer.getRendererSettings(name);</b>
    FileObject image = renderer.render(toRender, <b>mySettings</b>);
    if (image != null) {
        try {
            DataObject dob = DataObject.find (image);
            Node n = dob.getNodeDelegate();
            OpenCookie ck = (OpenCookie) n.getLookup().lookup(OpenCookie.class);
            if (ck != null) {
                ck.open();
            }
        } catch (DataObjectNotFoundException e) {
            //Should never happen
            Exceptions.printStackTrace(e);
        }
    }
}</pre>

            </ol>

        </div>

        <p>With that, you should be able to clean, build and run the application and
            be able to run POV-Ray and generate an image in the <code>images/</code>
            subdirectory of your project:</p>

        <p><a href="../images/tutorials/povray/71/ch7/pic1.png"><img alt="" src="../images/tutorials/povray/71/ch7/pic2.png"/></a></p>

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

        <p>The <a href="nbm-povray-8.html">next section</a> will cover implementing
            <code>ViewService</code> and adding actions for that.</p>

    </body>

</html>
