<!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>NetBeans Platform Feed Reader Tutorial for NetBeans Platform for 7.1</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="FeedReader on 7.1."/>
        <!--      Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. -->
        <!--     Use is subject to license terms.-->
    </head>

    <body>

        <h1>NetBeans Platform Feed Reader Tutorial</h1>

        <p>
            Welcome to the NetBeans Platform Feed Reader tutorial. 
            The Feed Reader that you create in this
            tutorial is a simple RSS/Atom feed browser, modeled 
            after the Sage plug-in for Mozilla Firefox. It 
            presents a tree of feeds with subnodes representing 
            individual feed entries that you can open in a browser.</p>

        <p>To illustrate the end result, here you see the Feed Reader that
            you will create in this tutorial, displaying a feed entry from the
            <a href="https://netbeans.org/rss-091.xml">NetBeans Highlights feed</a>:</p>

        <p><img src="../../images/tutorials/feedreader/70/feedreader.png" alt="feedreader result"/></p>

        <p><b class="notes">Note:</b> This document uses NetBeans IDE 7.1 and NetBeans Platform 7.1. If you
            are using an earlier version, see <a href="../70/nbm-feedreader.html">the previous version
                of this document</a>.</p>

        <p><b>Contents</b></p>

        <p><img src="../../images/articles/71/netbeans-stamp.png" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 7.1" title="Content on this page applies to NetBeans IDE 7.1"/></p>
        <ul class="toc">
            <li><a href="#knowledge">Prerequisite Knowledge</a></li>
            <li><a href="#setting">Setting Up the Application</a></li>
            <li><a href="#creating">Creating the Feed Reader Window</a></li>
            <li><a href="#running">Trying Out the Application</a></li>
            <li><a href="#adding">Adding Code to the Application</a>
                <ul>
                    <li><a href="#dep1">Specifying the Application's Dependencies</a></li>
                    <li><a href="#dep2">Setting Dependencies Between Library Wrapper Modules</a></li>
                    <li><a href="#rssfeeds">Creating the RssFeeds Folder</a></li>
                    <li><a href="#feedobject">Creating the Feed Object</a></li>
                    <li><a href="#feedwindow">Extending the Feed Window</a></li>
                    <li><a href="#root">Creating the Root Node</a></li>
                    <li><a href="#rssfolderchildren">Creating the Root Node Children</a></li>
                    <li><a href="#action1">Creating the Add Feed Action</a></li>
                    <li><a href="#action2">Creating the Add Folder Action</a></li>
                    <li><a href="#feed">Creating the Feed Node</a></li>
                    <li><a href="#entry">Creating the Entry Node</a></li>
                </ul>
            </li>
            <li><a href="#running">Running the Application</a></li>
            <li><a href="#troubleshooting">Troubleshooting</a></li>
        </ul>

        <p><b>To follow this tutorial, you need the software and resources listed in the following 
                table.</b></p>

        <table>
            <tbody>
                <tr>
                    <th class="tblheader" scope="col">Software or Resource</th>
                    <th class="tblheader" scope="col">Version Required</th>
                </tr> 
                <tr>
                    <td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td>
                    <td class="tbltd1">version 7.1</td>
                </tr>
                <tr>
                    <td class="tbltd1"><a href="http://java.sun.com/javase/downloads/index.jsp">Java Developer Kit (JDK)</a></td>
                    <td class="tbltd1">version 6 or above</td>
                </tr>
                <tr>
                    <td class="tbltd1"><a href="http://repo1.maven.org/maven2/net/java/dev/rome/rome/1.0.0">Rss and atOM utilitiEs</a></td>
                    <td class="tbltd1"></td>
                </tr>
                <tr>
                    <td class="tbltd1"><a href="http://repo1.maven.org/maven2/net/java/dev/rome/rome-fetcher/1.0.0">Rome Fetcher</a></td>
                    <td class="tbltd1"></td>
                </tr>
                <tr>
                    <td class="tbltd1"><a href="http://jdom.org/downloads/index.html">JDom</a></td>
                    <td class="tbltd1"></td>
                </tr>
                <tr>
                    <td class="tbltd1"><a href="https://netbeans.org/files/documents/4/550/feedreader-images.zip">FeedReader icon and splash screen</a></td>
                    <td class="tbltd1"></td>
                </tr>
            </tbody>
        </table>



        <h2><a name="knowledge"></a>Prerequisite Knowledge</h2>
        <p>This is not a beginner's tutorial. You are assumed not only to
            be familiar with Java and with Swing, but with the basic
            concepts and processes of the NetBeans Platform. At the very
            least, you should be aware of the following two documents
            and, ideally, you will have worked through them and understood
            the topics they address:</p>

        <ul>
            <li><a href="http://refcardz.dzone.com/refcardz/netbeans-platform-70">NetBeans Platform 7 DZone Refcard</a>.
                Anyone getting started with the NetBeans Platform must have this DZone RefCard, which explains
                the benefits, scope, and features of the NetBeans Platform. It outlines the most important
                APIs and provides many tips and tricks.</li>
            <!--    <li><a href="https://platform.netbeans.org/tutorials/nbm-feedreader_background.html">Preparing to Create the FeedReader Application</a>. This
             document provides the background of this tutorial. It walks
            you through everything you will do in this tutorial, conceptually.
             It also shows you
            where you can find the source code of the sample that you
            build in this tutorial.</li>-->
            <li><a href="nbm-quick-start.html">NetBeans Platform Quick Start</a>.
                This short tutorial guides you through a complete process
                for building a rich-client application on top of the NetBeans
                Platform. The major development stages and tools are covered,
                and a modular application is the result of the tutorial. This tutorial
                also introduces crucial classes used in the tutorial below, in particular
                the classes <a href="http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/Lookup.html">Lookup</a>,
                <a href="http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/LookupListener.html">LookupListener</a>,
                and <a href="http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/lookup/InstanceContent.html">InstanceContent</a>.</li>
        </ul>

        <h2><a name="setting"></a>Setting Up the Application</h2>
        <p>In NetBeans IDE, building an application on top of the NetBeans Platform
            starts with generating a number of files which will
            serve as the foundation of your application. For example,
            the IDE provides several project wizards that set up all
            the basic files needed by modules and applications built
            on the NetBeans Platform.</p>
        <ul>
            <li>
                <b>NetBeans Platform Application.</b> A project that groups a set of 
                module projects and library wrapper module projects that have dependencies on 
                each other, and lets you deploy them together as a unit. Automatically included
                are a subset of the modules that make up the NetBeans Platform.</li>
            <li>
                <b>Module Suite.</b> Same as above, except that the pre-included modules are
                more than only those relating to the NetBeans Platform&#8212;in this case,
                all the modules that make up NetBeans IDE are included as well.</li>
            <li>
                <b>Library Wrapper Module.</b> A project that puts a library JAR file on its classpath and exports some or all of the JAR file's packages from the module as public packages.</li>
            <li>
                <b>Module.</b> A project for implementing the functionality, business logic, and user interface of a module or application built on the NetBeans Platform.</li>
        </ul>
        <div class="indent">
            <h3>
                Creating the Application Skeleton</h3>
            <ol>
                <li>
                    <p>Choose File &gt; New Project (Ctrl-Shift-N). Under
                        Categories, select NetBeans Modules. Under Projects, select NetBeans Platform Application. 
                        You should see the following:</p>
                    <p><img alt="project wizard"  src="../../images/tutorials/feedreader/70/paintapp-proj-wiz.png" /></p>
                    <p class="tips">Depending on the modules installed in your IDE, different categories may be shown
                        in the Categories list above.</p>
                    <p>Click Next.</p></li>
                <li>
                    <p>In the Name and Location panel, type <tt>FeedReader</tt>
                        in Project Name. Change the Project Location to any
                        directory on your computer.</p>
                    <p><img alt="project wizard"  src="../../images/tutorials/feedreader/70/paintapp-proj-wiz2.png" /></p>
                    <p>Click Finish.</p></li>
            </ol>

            <p>The IDE creates the <tt>FeedReader</tt>
                project, which looks as follows in the
                Projects window:</p>
            <p><img alt="projects window"  src="../../images/tutorials/feedreader/70/suite-project.png"/></p>

            <p>The project will contain the custom module projects that you
                will create in the following sections. </p>

            <h3>
                Wrapping the Libraries</h3>

            <p>You could bundle the entire Feed Reader application into a
                single module. However, the application needs the Rome, Rome Fetcher, and JDom libraries:</p>
            <ul>
                <li>
                    <b>Rome.</b> Reads RSS and Atom feeds, using a very simple API. </li>
                <li>
                    <b>Rome Fetcher.</b> Allows the retrieval of feeds via HTTP. </li>
                <li>
                    <b>JDom.</b> Is an XML parsing API. The only reason the Feed Reader will need it is because the Rome library uses it.</li>
            </ul>

            <p class="tips">Later, if you want to extend the Feed Reader
                application with more modules that may use these libraries,
                it would be better for them to depend on just the library modules,
                rather than the entire Feed Reader. Also, library modules can
                be "autoloading", which means that NetBeans will only load them
                when needed. Until that happens, it won't take up any memory at runtime.</p>
            <ol>
                <li><p>Right-click the Modules node in the project in
                        the Projects window, as shown below, and click Add New Library:</p>
                    <p><img alt="add new library"  src="../../images/tutorials/feedreader/70/add-lib0.png"/></p></li>

                <li>
                    In the Select Library panel, browse
                    to the folder where you downloaded JDom, and then select <tt>jdom.jar</tt>
                    and <tt>LICENSE.txt.</tt>
                    Click Next.</li>
                <li>
                    <p>In the Name and Location panel, accept all the defaults.</p>


                    <p class="tips"> The library wrapper module project
                        will be stored within the application project. 
                        You could also store it somewhere else, but for 
                        versioning purposes it is a good idea to put it within
                        the application project. Therefore, the <tt>FeedReader</tt>
                        application project is selected in the 
                        Add to Module Suite drop-down.</p>
                    <p>Click Next.</p></li>
                <li>
                    <p>In the Basic Module Configuration panel, type <tt>org.jdom</tt>
                        as the code name base and leave all the other defaults unchanged. Click Finish.</p>
                    <p>The new library wrapper module project opens 
                        in the IDE and displays in the Projects window.
                        You should now see the following in the Projects
                        window:</p>

                    <p><img alt="projects window"  src="../../images/tutorials/feedreader/70/lib-wiz2.png"/></p>
                    <p class="tips"> A frequent point of confusion is that you see two different "jdom" nodes above,
                        each accompanied by a purple icon. The first of these, above, shows the relationship of the
                        "jdom" module to the whole application. The second is the "jdom" project itself, containing
                        its sources and libraries. This pattern is used throughout the application, with each module
                        being shown in two different ways, as above.</p>                

                </li>
                <li>
                    Return to step 1 of this section and create a library wrapper module project for Rome.
                    Use code name base "org.rome" and accept all the other defaults.</li>
                <li>
                    Return to step 1 of this section and create a library wrapper module project for Rome Fetcher.
                    Use code name base "org.fetcher" and accept all the other defaults.</li>
            </ol>

            <p>You now have an application skeleton,
                with three library wrapper module projects,
                providing many useful Java classes that you will
                be able to make use of throughout this tutorial:</p>
            <p><img alt="projects window"  src="../../images/tutorials/feedreader/70/lib-wiz3.png"/></p>

            <h3>
                Creating the Module Project </h3>
            <p>In this section, we create a project for the functionality
                that our application will provide. The project will make use of
                the classes made available by the library wrapper modules that
                we created in the previous section.</p>
            <ol>
                <li>
                    <p>Right-click the Modules node in the application project in
                        the Projects window, as shown below, and click Add New:</p>
                    <p><img alt=""  src="../../images/tutorials/feedreader/70/module-project1.png"/></p>
                </li>
                <li>In the Name and Location panel, type <tt>FeedReader</tt>
                    in Project Name. Accept all the other defaults. Click Next.</li>
                <li>In the Basic Module Configuration panel, type <tt>org.myorg.feedreader</tt>
                    in Code Name Base.</li>
                <li>Do not select "Generate OSGi Bundle". Click Finish.</li>
            </ol>
            <p>
                The IDE creates the FeedReader project. 
                The project contains all of the module's sources and project 
                metadata, such as the project's Ant build script. The project 
                opens in the IDE. You can view its logical structure in the 
                Projects window (Ctrl-1) and its file structure in the Files 
                window (Ctrl-2). The Projects window should now show the 
                following:</p>

            <p><img alt=""  src="../../images/tutorials/feedreader/70/module.png"/></p>

        </div>
        <p>You have now created the source structure
            of your new application. In the next section,
            we will begin adding some code.</p>

        <h2><a name="creating"></a>
            Creating the Feed Reader Window</h2>
        <p>
            In this section you use the Window wizard to generate files that create a 
            custom windowing component and an action to invoke it. Right after finishing 
            this section, you are shown how to try out the files that the Window wizard generates for you.</p>
        <div class="indent">
            <ol>
                <li>
                    <p>Right-click the <tt>FeedReader</tt>
                        module project node and choose New &gt; Other. Under Categories, select Module Development. 
                        Under File Types, select Window, as shown below:</p>


                    <img alt=""  src="../../images/tutorials/feedreader/70/windowcomp-wiz.png"/>


                    <p>Click Next.</p></li>
                <li>
                    <p>In the Basic Settings panel, select <tt>explorer</tt>
                        in the drop-down list and click Open on Application 
                        Start. Click Next.</p></li>
                <li>
                    <p>In the Name and Location panel, type Feed in the Class Name Prefix field. In the Icon field, browse to the location
                        where you saved <tt>rss16.gif (<img alt=""  src="../../images/tutorials/feedreader/rss16.gif" />).</tt>
                        The GIF file will be shown in the menu item that 
                        invokes the action. Click Finish.</p></li>
            </ol>
            <p>The new <tt>FeedTopComponent</tt> class is now shown in the Projects window, as well
                as in the Design view of the Matisse GUI Builder. Open it into
                the Source view and you should see the following:</p>

            <pre class="examplecode" style="overflow:auto;width:680px;">import org.openide.util.NbBundle;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;

<a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-settings/org/netbeans/api/settings/ConvertAsProperties.html">@ConvertAsProperties</a>(dtd = "-//org.myorg.feedreader//Feed//EN",
autostore = false)
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.Description.html">@TopComponent.Description</a>(preferredID = "FeedTopComponent",
iconBase = "org/myorg/feedreader/rss16.gif",
persistenceType = TopComponent.PERSISTENCE_ALWAYS)
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.Registration.html">@TopComponent.Registration</a>(mode = "explorer", openAtStartup = true)
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionID.html">@ActionID</a>(category = "Window", id = "org.myorg.feedreader.FeedTopComponent")
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionReference.html">@ActionReference</a>(path = "Menu/Window" /*, position = 333 */)
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.OpenActionRegistration.html">@TopComponent.OpenActionRegistration</a>(displayName = "#CTL_FeedAction",
preferredID = "FeedTopComponent")
public final class FeedTopComponent extends <a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.html">TopComponent</a> {

    private FeedTopComponent() {
        setName(NbBundle.getMessage(FeedTopComponent.class, "CTL_FeedTopComponent"));
        setToolTipText(NbBundle.getMessage(FeedTopComponent.class, "HINT_FeedTopComponent"));
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // &lt;editor-fold defaultstate="collapsed" desc="Generated Code"&gt;
    private void initComponents() {
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );
    }// &lt;/editor-fold&gt;
    // Variables declaration - do not modify
    // End of variables declaration

    @Override
    public void componentOpened() {
        // TODO add custom code on component opening
    }

    @Override
    public void componentClosed() {
        // TODO add custom code on component closing
    }

    void writeProperties(java.util.Properties p) {
        // better to version settings since initial version as advocated at
        // http://wiki.apidesign.org/wiki/PropertyFiles
        p.setProperty("version", "1.0");
    }

    void readProperties(java.util.Properties p) {
        String version = p.getProperty("version");
    }

}</pre>
            <p>When you build the module, the class annotations that 
                you see at the top of the class above will be converted to XML tags in a file that will be 
                contributed to the central registry of the application. The XML file will 
                be named "generated-layer.xml" and will be found in the "build\classes\META-INF" 
                folder of your module, which you can see if the Files window (Ctrl-2) is open 
                in the IDE. This file is created at compile-time and contains XML entries generated
                from the NetBeans annotations that you have defined in your Java classes. Together 
                with the "layer.xml" file that your module provides, the 
                "generated-layer.xml" file defines the contributions that the module makes to the central registry.</p> 
            <p class="tips">Valid values for the "mode" parameter, in <tt>@TopComponent.Registration</tt>, depend
                on the modes registered in the central registry. Commonly, these include "editor", "explorer", "properties",
                and "output", among others. See the section "Creating the RssFeeds Folder" below to learn about how
                you can explore the central registry and inspect its folders and files.
                if the <a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/NbBundle.Messages.html">@Messages</a> annotation were to be used.</p>
            <p class="tips">The code above could be even more idiomatic NetBeans Platform code
                if the <a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/NbBundle.Messages.html">@Messages</a> annotation were to be used.</p>
        </div>
        <h2><a name="running"></a>Trying Out the Application</h2>
        <p>
            Without having typed a single line of code, you can already 
            take your application for a spin. Trying it out means deploying
            the modules to the NetBeans Platform and then checking to 
            see that the empty Feed 
            Window displays correctly.</p>
        <div class="indent">
            <ol>

                <li><p>In the Projects window, right-click the <tt>FeedReader</tt>
                        project.</p></li>
                <li><p>Choose Run.</p></li>

            </ol>

            <p>The application starts up. You see a splash screen.
                Then the application opens and displays the 
                new Feed Window, as an explorer window, shown
                below:</p>

            <p><img alt=""  src="../../images/tutorials/feedreader/70/feedreader-1.png"/></p>

            <p><strong class="notes">Note: </strong> What you now have is an application consisting
                of the following modules:</p>
            <ul>
                <li>The modules provided by the NetBeans Platform, for bootstrapping
                    the application, lifecycle management, window system, menu bars, toolbars, and other infrastructural
                    concerns.</li>
                <li>The three library wrapper modules that you created in this tutorial.</li>
                <li>The FeedReader functionality module that
                    you created in this tutorial, for providing the Feed window.</li>
            </ul>


            <p>In the application's Window menu, you should see the new menu item,
                which you can use for opening the Feed window, if it is closed.</p>
        </div>
        <p>As you can see, without having done any coding, we have a 
            complete application. It doesn't do much yet, but the entire
            infrastructure exists and works as one would expect. Next, we begin using some
            of the NetBeans APIs, to add code to our application.</p>

        <h2><a name="adding"></a>
            Adding Code to the Application</h2>
        <p>
            Now that you have laid the basis for your application, it's time to
            begin adding your own code. Before doing so, you need to specify
            the application's dependencies. Dependencies are modules that
            provide the NetBeans APIs that you will extend or implement. Then, 
            you will use the New File wizard and the Source Editor to create 
            and code the classes that make up the Feed Reader application.</p>
        <div class="indent">
            <h3><a name="dep1"></a>
                Specifying the Application's Dependencies</h3>

            <p>You need to subclass several classes that belong to the NetBeans APIs.
                The classes belong to modules that need to be declared as dependencies
                of your Feed Reader application. Use the Project Properties dialog
                box for this purpose, as explained in the steps below.</p>
            <ol>
                <li>
                    <p>In the Projects window, right-click the
                        <tt>FeedReader</tt>
                        module project and choose Properties. In the 
                        Project Properties dialog box, click Libraries.
                        Notice that some APIs have already been declared as
                        Module Dependencies, thanks to the Window wizard you used
                        earlier.</p></li>
                <li>
                    Click Add Dependency.
                    You will need the following APIs. Some have been
                    added by the Window wizard. Add the others yourself:
                    <pre class="examplecode"><a href="http://bits.netbeans.org/dev/javadoc/org-openide-actions/org/openide/actions/doc-files/api.html">Actions APIs</a>
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-loaders/org/openide/loaders/doc-files/api.html">Datasystems API</a>
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-dialogs/org/openide/package-summary.html">Dialogs API</a>
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-explorer/org/openide/explorer/doc-files/api.html">Explorer and Property Sheet API</a>
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-filesystems/org/openide/filesystems/doc-files/api.html">File System API</a>
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/lookup/doc-files/lookup-api.html">Lookup API</a>
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-nodes/org/openide/nodes/doc-files/api.html">Nodes API</a>
rome
rome-fetcher
<a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-settings/overview-summary.html">Settings API</a>
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/overview-summary.html">UI Utilities API</a>
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/overview-summary.html">Utilities API</a>
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/package-summary.html">Window System API</a></pre>


                    <p>Click OK to exit the Project Properties dialog box.</p></li>

                <li><p>Expand the <tt>FeedReader</tt> project's Libraries
                        node and notice the list of modules that are now
                        available to this project:</p>


                    <img alt=""  src="../../images/tutorials/feedreader/70/add-lib5.png"/>

                </li>
            </ol>

            <h3><a name="dep2"></a>
                Setting Dependencies Between Library Wrapper Modules</h3>

            <p>Now that we have set dependencies on the NetBeans API modules
                that we will use, let's also set dependencies between our
                library wrapper modules. For example, the Rome JAR makes use
                of classes from the JDom JAR. Now that these are wrapped in
                separate library wrapper modules, we need to specify the
                relationship between the JARs via the library wrapper module's
                Project Properties dialog box.</p>

            <ol>
                <li>
                    <p>First, lets make Rome dependent on JDom. Right-click the Rome
                        library wrapper module project in the Projects window and choose
                        Properties. In the Project Properties dialog box, click Libraries
                        and then click Add Dependency. Add <tt>jdom</tt>. Click OK
                        to exit the Project Properties dialog box. When you expand
                        the Libraries node in the Rome project, you should now see the following:</p>
                    <p><img alt="" src="../../images/tutorials/feedreader/70/props-jdom.png"/></p>
                </li>
                <li>
                    <p>Finally, since Rome Fetcher depends on both
                        Rome and JDom, you need to make Rome Fetcher
                        dependent on Rome. Do so following the same instructions
                        as the above, so that Rome Fetcher depends on Rome, as shown below:</p>

                    <p><img alt="" src="../../images/tutorials/feedreader/70/props-rome.png"/></p>

                    Because Rome already 
                    depends on JDom, you do not need to make 
                    Rome Fetcher dependent on JDom.</li>
            </ol>
            <h3><a name="rssfeeds"></a>
                Creating the RssFeeds Folder</h3>

            <p>You will use the IDE's user interface to add a folder
                to the <tt>layer.xml</tt> file, which the module
                will contribute to the application's central registry at runtime. The folder will contain
                our RSS feed objects. Later, you will add code to <tt>FeedTopComponent.java</tt>, which
                was created for you by 
                the Window wizard, to view the content of this folder.</p>
            <ol>
                <li><p>Right-click the <tt>FeedReader</tt>
                        module project node and choose New &gt; Other &gt; Module Development &gt; XML Layer.
                    Click Finish. You now have an XML file, registered in the manifest of the module,
                    which the module will contribute to the central registry (the virtual filesystem)
                    of the application.</p></li>
                <li>
                    <p>In the Projects window, expand the <tt>FeedReader</tt>
                        module project node and then expand the XML Layer
                        node. </p>
                    <p class="tips">When you expand the subnodes, you see <tt>"&lt;this layer&gt;"</tt>, containing
                        the folders and files registered in the current module's layer file,
                        as well as <tt>"&lt;this layer in context&gt;"</tt>, which merges all the folders
                        and files from all the modules in the whole application:</p>
                    <p><img alt="" src="../../images/tutorials/feedreader/70/expanded-layer.png"/></p></li>
                <li>
                    <p>Right-click the <tt>&lt;this layer&gt;</tt>
                        node and choose New &gt; Folder:</p>
                    <p><img alt="" src="../../images/tutorials/feedreader/70/expanded-layer2.png"/></p>
                </li>
                <li>
                    Type <tt>RssFeeds</tt>
                    in the New Folder dialog box. Click OK.
                </li>
                <li>Double-click the node for the <tt>layer.xml</tt>
                    file so that it opens in the Source Editor. Notice that this entry has been added:
                    <tt>&lt;folder name=&quot;RssFeeds&quot;/&gt;</tt>
                </li>
            </ol>
            <p>You have now created a new folder in the central registry. The central registry
                is also known as the "System FileSystem". Read more about <a href="http://wiki.netbeans.org/DevFaqSystemFilesystem">the central
                    registry here</a>.</p>
            <h3><a name="feedobject"></a>
                Creating the Feed Object</h3>

            <p>Next you create a plain Java class that encapsulates a URL and its associated Rome feed.</p>
            <ol>
                <li>
                    Right-click the <tt>FeedReader</tt>
                    module project node, choose New &gt; Java Class.</li>
                <li>
                    Name the class <tt>Feed</tt>
                    and select <tt>org.myorg.feedreader</tt>
                    in the Package drop-down. Click Finish.</li>
                <li>
                    In the Source Editor, replace the default <tt>Feed</tt>
                    class with the following:
                    <pre class="examplecode">public class Feed implements Serializable {

    private static final long serialVersionUID = 1L;

    private static final FeedFetcher FEED_FETCHER =
            new HttpURLFeedFetcher(HashMapFeedInfoCache.getInstance());

    private transient SyndFeed syndFeed;
    private final URL url;
    private String name;

    public Feed(URL url) {
        this.url = url;
        name = url.toExternalForm();
    }

    public URL getURL() {
        return url;
    }

    public SyndFeed getSyndFeed() throws IOException {
        if (syndFeed == null) {
            try {
                syndFeed = FEED_FETCHER.retrieveFeed(url);
                String title = syndFeed.getTitle();
                if (title != null) {
                    name = title;
                }
            } catch (Exception ex) {
                throw (IOException) new IOException(ex.toString()).initCause(ex);
            }
        }
        return syndFeed;
    }

    @Override
    public String toString() {
        return name;
    }

    public static Feed getSample() {
        try {
            return new Feed(new URL(NbBundle.getMessage(Feed.class, "URL_sample_feed")));
        } catch (MalformedURLException x) {
            throw new AssertionError(x);
        }
    }

}</pre>
                </li>
            </ol>
            <p>A lot of code is underlined, because you have not declared their packages. You do this in the next steps. </p>

            <p>Take the following steps to reformat the file and declare its dependencies:</p>
            <ol>
                <li>
                    Press Alt-Shift-F to format the code. </li>
                <li>

                    <p>Press Ctrl-Shift-I and make sure
                        the following import statements are selected:</p>

                    <p><img alt=""  src="../../images/tutorials/feedreader/70/nb-imports.png"/></p>

                    <p>Click OK, and the IDE adds the following import statements
                        to the class:</p>

                    <pre class="examplecode">import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.fetcher.FeedFetcher;
import com.sun.syndication.fetcher.impl.HashMapFeedInfoCache;
import com.sun.syndication.fetcher.impl.HttpURLFeedFetcher;
import java.io.IOException;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import org.openide.util.NbBundle;</pre>
                </li>
            </ol>

            <p>All the red underlining should now have disappeared. If not,
                do not continue with this tutorial until you have solved the problem.</p>
            <h3><a name="feedwindow"></a>
                Extending the Feed Window</h3>

            <p>In this section, we use a NetBeans Swing component called <tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-explorer/org/openide/explorer/view/BeanTreeView.html">BeanTreeView</a></tt>
                to display a hierarchy of feeds in our <tt>TopComponent</tt>.</p>

            <ol>
                <li>
                    Double-click <tt>FeedTopComponent.java</tt>
                    and then click the Source button,
                    so that the <tt>TopComponent</tt> opens in the Source Editor.</li>
                <li>
                    Type <tt>implements <a href="http://bits.netbeans.org/dev/javadoc/org-openide-explorer/org/openide/explorer/ExplorerManager.Provider.html">ExplorerManager.Provider</a></tt>
                    at the end of the class declaration.</li>
                <li>
                    Press Alt-Enter in the line and click on the suggestion. The IDE adds an import statement for the required
                    package <tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-explorer/org/openide/explorer/ExplorerManager.html">org.openide.explorer.ExplorerManager</a></tt>
                    .</li>
                <li>
                    Press Alt-Enter again and click on the suggestion. The IDE implements the abstract
                    method <tt>getExplorerManager()</tt>. </li>
                <li>
                    Type <tt>return manager;</tt>
                    in the body of the new <tt>getExplorerManager()</tt>
                    method. Press Alt-Enter in the line and let the IDE create a field called <tt>manager</tt>
                    for you. Replace the default definition with this one:
                    <pre class="examplecode">private final ExplorerManager manager = new ExplorerManager();</pre>
                </li>
                <li>
                    Right below the field declaration in the previous step, declare this one:
                    <pre class="examplecode">private final BeanTreeView view = new BeanTreeView();</pre>
                </li>
                <li>
                    Finally, add the following code to the end of the constructor:
                    <pre class="examplecode">setLayout(new BorderLayout());
add(view, BorderLayout.CENTER);
manager.setRootContext(new RssNode.RootRssNode());
ActionMap map = getActionMap();
map.put("delete", ExplorerUtils.actionDelete(manager, true));
associateLookup(ExplorerUtils.createLookup(manager, map));</pre>
                </li>
            </ol>

            <p>
                Now a lot of code is underlined, because you have not declared their associated packages. You do this in the next steps. </p>
            <p>
                Take the following steps to reformat the file and declare its dependencies:</p>
            <ol>
                <li>
                    Press Alt-Shift-F to format the code. </li>
                <li>
                    Press Ctrl-Shift-I and the IDE adds several import 
                    statements below the package statement. The complete 
                    list of import statements should be as follows:

                    <pre class="examplecode">import java.awt.BorderLayout;
import java.util.logging.Logger;
import javax.swing.ActionMap;
import org.openide.util.NbBundle;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
import org.openide.util.ImageUtilities;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerUtils;
import org.openide.explorer.view.BeanTreeView;</pre>

                </li>
                <li>
                    Note that the line <tt>manager.setRootContext(new RssNode.RootRssNode());</tt>
                    is still underlined in red, because you have not created <tt>RssNode.java</tt>
                    yet. This you will do in the next subsection. All other red underlining should now have disappeared. If not, do not continue with this tutorial until you have solved the problem.</li>
            </ol>
            <h3><a name="root"></a>Creating the Root Node</h3>

            <p>The top level node of our Feed Reader is provided
                by the RssNode class. The class extends <tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-nodes/org/openide/nodes/AbstractNode.html">AbstractNode</a></tt>,
                which is the generic convenience class for creating
                your own Nodes. It creates its child Nodes
                by using the 'RssFeeds' folder that you
                created in the "Creating the RssFeeds Folder" section
                earlier in this tutorial. In addition to child Nodes,
                the RootNode has a display name and an Action for
                creating new feeds.</p>

            <p>Take the following steps to create the RootNode class:   </p>

            <ol>
                <li>
                    Create <tt>RssNode.java</tt>
                    in the <tt>org.myorg.feedreader</tt>
                    package.</li>
                <li>
                    Replace the default class with the following:
                    <pre class="examplecode">import javax.swing.Action;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataFolder;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.nodes.FilterNode;
import org.openide.nodes.Node;
import org.openide.util.NbBundle;

public class RssNode extends <a href="http://bits.netbeans.org/dev/javadoc/org-openide-nodes/org/openide/nodes/FilterNode.html">FilterNode</a> {

    /** Declaring the children of the root RSS node */
    public RssNode(Node folderNode) {
        super(folderNode, new RssFolderChildren(folderNode));
    }

    /** Declaring the Add Feed action and Add Folder action */
    @Override
    public Action[] getActions(boolean popup) {
        DataFolder df = getLookup().lookup(DataFolder.class);
        return new Action[] {
            new AddRssAction(df),
            new AddFolderAction(df)
        };
    }

    /** Getting the root node */
    public static class RootRssNode extends RssNode {
        public RootRssNode() throws DataObjectNotFoundException {
            super(DataObject.find(
                    FileUtil.getConfigFile("RssFeeds")).getNodeDelegate());
        }
        @Override
        public String getDisplayName() {
            return NbBundle.getMessage(RssNode.class, "FN_title");
        }
    }

}</pre>
                </li>
            </ol>
            <p>Several red underline markings remain in the class, because
                you have not yet created the RssFolderChildren class, the OneFeedNode class, the AddRssAction class, and the AddFolderAction class.</p>


            <h3><a name="rssfolderchildren"></a>Creating the Root Node Children</h3>

            <p>In this section, we create the children of the root node. Each child
                is a folder, containing RSS feeds. The RSS feeds, in turn,
                contain the articles that are shown in a browser.</p>

            <p>To create this class, take the following steps:</p>

            <ol>
                <li>
                    Create <tt>RssFolderChildren.java</tt>
                    in the <tt>org.myorg.feedreader</tt>
                    package.</li>
                <li>
                    <p>Replace the default class with the following:</p>
                    <pre class="examplecode">import java.io.IOException;
import org.netbeans.feedreader.Feed;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataFolder;
import org.openide.nodes.FilterNode;
import org.openide.nodes.Node;
import org.openide.util.Exceptions;

/** Getting the children of the root node */
public class RssFolderChildren extends FilterNode.Children {

    RssFolderChildren(Node rssFolderNode) {
        super(rssFolderNode);
    }

    @Override
    protected Node[] createNodes(Node n) {
        if (n.getLookup().lookup(DataFolder.class) != null) {
            return new Node[]{new RssNode(n)};
        } else {
            Feed feed = getFeed(n);
            if (feed != null) {
                try {
                    return new Node[]{new OneFeedNode(n, feed.getSyndFeed())};
                } catch (IOException ioe) {
                    Exceptions.printStackTrace(ioe);
                }
            }
        }
        // best effort
        return new Node[]{new FilterNode(n)};
    }

    /** Looking up a feed */
    private static Feed getFeed(Node node) {
        Feed f = FileUtil.getConfigObject("RssFeeds/sample.instance", Feed.class);
        if (f == null) {
            throw new IllegalStateException("Bogus file in feeds folder: " +
                    node.getLookup().lookup(FileObject.class));
        }
        return f;
    }

}</pre>

                </li>

            </ol>


            <h3><a name="action1"></a>Creating the Add Feed Action</h3>

            <p>In this section, we create the menu item that adds new
                feeds. As you can see in the previous section, the
                Add Feed Action is bound to the context-menu of the
                Root Node.</p>

            <p>To create this class, take the following steps:</p>

            <ol>
                <li>
                    Create <tt>AddRssAction.java</tt>
                    in the <tt>org.myorg.feedreader</tt>
                    package.</li>
                <li>
                    <p>Replace the default class with the following:</p>
                    <pre class="examplecode">import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.AbstractAction;
import org.netbeans.feedreader.Feed;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.filesystems.FileLock;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataFolder;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;

/** An action for adding a feed */
public class AddRssAction extends AbstractAction {

    private final DataFolder folder;

    public AddRssAction(DataFolder df) {
        super(NbBundle.getMessage(AddRssAction.class, "FN_addbutton"));
        folder = df;
    }

    public void actionPerformed(ActionEvent ae) {
        <a href="http://bits.netbeans.org/dev/javadoc/org-openide-dialogs/org/openide/NotifyDescriptor.html">NotifyDescriptor</a>.InputLine nd = new NotifyDescriptor.InputLine(
                NbBundle.getMessage(AddRssAction.class, "FN_askurl_msg"),
                NbBundle.getMessage(AddRssAction.class, "FN_askurl_title"),
                NotifyDescriptor.OK_CANCEL_OPTION,
                NotifyDescriptor.PLAIN_MESSAGE);

        Object result = <a href="http://bits.netbeans.org/dev/javadoc/org-openide-dialogs/org/openide/DialogDisplayer.html">DialogDisplayer</a>.getDefault().notify(nd);

        if (result.equals(NotifyDescriptor.OK_OPTION)) {
            String urlString = nd.getInputText();
            URL url;
            try {
                url = new URL(urlString);
            } catch (MalformedURLException e) {
                String message = NbBundle.getMessage(AddRssAction.class, "FN_askurl_err", urlString);
                Exceptions.attachLocalizedMessage(e, message);
                Exceptions.printStackTrace(e);
                return;
            }
            try {
                checkConnection(url);
            } catch (IOException e) {
                String message = NbBundle.getMessage(AddRssAction.class, "FN_cannotConnect_err", urlString);
                Exceptions.attachLocalizedMessage(e, message);
                Exceptions.printStackTrace(e);
                return;
            }
            Feed f = new Feed(url);
            FileObject fld = folder.getPrimaryFile();
            String baseName = "RssFeed";
            int ix = 1;
            while (fld.getFileObject(baseName + ix, "ser") != null) {
                ix++;
            }
            try {
                FileObject writeTo = fld.createData(baseName + ix, "ser");
                FileLock lock = writeTo.lock();
                try {
                    ObjectOutputStream str = new ObjectOutputStream(writeTo.getOutputStream(lock));
                    try {
                        str.writeObject(f);
                    } finally {
                        str.close();
                    }
                } finally {
                    lock.releaseLock();
                }
            } catch (IOException ioe) {
                Exceptions.printStackTrace(ioe);
            }
        }
    }

    private static void checkConnection(final URL url) throws IOException {
        InputStream is = url.openStream();
        is.close();
    }

}</pre>

                </li>

            </ol>

            <h3><a name="action2"></a>Creating the Add Folder Action</h3>

            <p>In this section, we create the menu item that adds new
                folders, in which new feeds can be created. As you can see in an earlier section, the
                Add Folder Action is bound to the context-menu of the
                Root Node.</p>

            <p>To create this class, take the following steps:</p>

            <ol>
                <li>
                    Create <tt>AddFolderAction.java</tt>
                    in the <tt>org.myorg.feedreader</tt>
                    package.</li>
                <li>
                    <p>Replace the default class with the following:</p>
                    <pre class="examplecode">import java.awt.event.ActionEvent;
import java.io.IOException;
import javax.swing.AbstractAction;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.loaders.DataFolder;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;

/** An action for adding a folder to organize feeds into groups */
public class AddFolderAction extends AbstractAction {

    private final DataFolder folder;

    public AddFolderAction(DataFolder df) {
        super(NbBundle.getMessage(AddFolderAction.class, "FN_addfolderbutton"));
        folder = df;
    }

    public void actionPerformed(ActionEvent ae) {
        <a href="http://bits.netbeans.org/dev/javadoc/org-openide-dialogs/org/openide/NotifyDescriptor.html">NotifyDescriptor</a>.InputLine nd = new NotifyDescriptor.InputLine(
                NbBundle.getMessage(AddFolderAction.class, "FN_askfolder_msg"),
                NbBundle.getMessage(AddFolderAction.class, "FN_askfolder_title"),
                NotifyDescriptor.OK_CANCEL_OPTION,
                NotifyDescriptor.PLAIN_MESSAGE);

        Object result = <a href="http://bits.netbeans.org/dev/javadoc/org-openide-dialogs/org/openide/DialogDisplayer.html">DialogDisplayer</a>.getDefault().notify(nd);

        if (result.equals(NotifyDescriptor.OK_OPTION)) {
            final String folderString = nd.getInputText();
            try {
                DataFolder.create(folder, folderString);
            } catch (IOException ex) {
                Exceptions.printStackTrace(ex);
            }
        }
    }

}</pre>

                </li>

            </ol>

            <h3><a name="feed"></a>Creating the Feed Node</h3>

            <p>Here we are concerned with the container for the article nodes, as shown below
                for the 'NetBeans Highlights' node:</p>

            <p>
                <img alt="" src="../../images/tutorials/feedreader/60-actions2.png"/>
            </p>

            <p>As can be seen, each of these nodes has
                a display name, retrieved from the feed, an icon, and a Delete menu item.</p>

            <p>Take the following steps to create this class:   </p>

            <ol>
                <li>
                    Create <tt>OneFeedNode.java</tt>
                    in the <tt>org.myorg.feedreader</tt>
                    package.</li>
                <li>
                    Replace the default class with the following:

                    <pre class="examplecode">import com.sun.syndication.feed.synd.SyndFeed;
import java.awt.Image;
import javax.swing.Action;
import org.openide.actions.DeleteAction;
import org.openide.nodes.FilterNode;
import org.openide.nodes.Node;
import org.openide.util.ImageUtilities;
import org.openide.util.Lookup;
import org.openide.util.actions.SystemAction;
import org.openide.util.lookup.Lookups;
import org.openide.util.lookup.ProxyLookup;

/** Getting the feed node and wrapping it in a FilterNode */
public class OneFeedNode extends <a href="http://bits.netbeans.org/dev/javadoc/org-openide-nodes/org/openide/nodes/FilterNode.html">FilterNode</a> {

    OneFeedNode(Node feedFileNode, SyndFeed feed) {
        super(feedFileNode,
                new FeedChildren(feed),
                new ProxyLookup(new Lookup[]{
                    Lookups.fixed(new Object[]{feed}),
                    feedFileNode.getLookup()
                }));
    }

    @Override
    public String getDisplayName() {
        SyndFeed feed = getLookup().lookup(SyndFeed.class);
        return feed.getTitle();
    }

    @Override
    public Image getIcon(int type) {
        return <a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/ImageUtilities.html">ImageUtilities</a>.loadImage("org/netbeans/feedreader/rss16.gif");
    }

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

    @Override
    public Action[] getActions(boolean context) {
        return new Action[]{SystemAction.get(<a href="http://bits.netbeans.org/dev/javadoc/org-openide-actions/org/openide/actions/DeleteAction.html">DeleteAction</a>.class)};
    }

}</pre>

                </li>

            </ol>

            <p>Several red underline markings remain in the class, because
                we have not created our <tt>FeedChildren</tt> class yet. Here it is:</p>

            <pre class="examplecode">import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import java.beans.IntrospectionException;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.util.NbCollections;

/** Defining the children of a feed node */
public class FeedChildren extends <a href="http://bits.netbeans.org/dev/javadoc/org-openide-nodes/org/openide/nodes/Children.Keys.html">Children.Keys&lt;SyndEntry&gt;</a> {

    private final SyndFeed feed;

    public FeedChildren(SyndFeed feed) {
        this.feed = feed;
    }

    @Override
    protected void addNotify() {
        setKeys(<a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/NbCollections.html#checkedListByCopy%28java.util.List,%20java.lang.Class,%20boolean%29">NbCollections.checkedListByCopy</a>(feed.getEntries(), SyndEntry.class, true));
    }

    @Override
    public Node[] createNodes(SyndEntry entry) {
        try {
            return new Node[]{new EntryBeanNode(entry)};
        } catch (IntrospectionException ex) {
            assert false : ex;
            return new Node[0];
        }
    }

}</pre>


            <h3><a name="entry"></a>Creating the Entry Node</h3>

            <p>Finally, we deal with the lowest level nodes, those
                that represent articles provided by the feed.</p>

            <p>To create this class, take the following steps:</p>

            <ol>
                <li>
                    Create <tt>OneEntryNode.java</tt>
                    in the <tt>org.myorg.feedreader</tt>
                    package.</li>
                <li>
                    Replace the default class with the following:
                    <pre class="examplecode">import com.sun.syndication.feed.synd.SyndEntry;
import java.beans.IntrospectionException;
import javax.swing.Action;
import org.openide.actions.OpenAction;
import org.openide.nodes.BeanNode;
import org.openide.nodes.FilterNode;
import org.openide.util.actions.SystemAction;
import org.openide.util.lookup.Lookups;

/** Wrapping the children in a FilterNode */
public class OneEntryNode extends <a href="http://bits.netbeans.org/dev/javadoc/org-openide-nodes/org/openide/nodes/FilterNode.html">FilterNode</a> {

    private final SyndEntry entry;

    public OneEntryNode(SyndEntry entry) throws IntrospectionException {
        super(new BeanNode&lt;SyndEntry&gt;(entry), Children.LEAF,
                Lookups.fixed(entry, new EntryOpenCookie(entry)));
        this.entry = entry;
    }

    /** Using HtmlDisplayName ensures any HTML in RSS entry titles are properly handled, escaped, entities resolved, etc. */
    @Override
    public String getHtmlDisplayName() {
        return entry.getTitle();
    }

    /** Making a tooltip out of the entry's description */
    @Override
    public String getShortDescription() {
        StringBuilder sb = new StringBuilder();
        sb.append("Author: ").append(entry.getAuthor()).append("; ");
        if (entry.getPublishedDate() != null) {
            sb.append("Published: ").append(entry.getPublishedDate().toString());
        }
        return sb.toString();
    }

    /** Providing the Open action on a feed entry */
    @Override
    public Action[] getActions(boolean popup) {
        return new Action[]{SystemAction.get(<a href="http://bits.netbeans.org/dev/javadoc/org-openide-actions/org/openide/actions/OpenAction.html">OpenAction</a>.class)};
    }

    @Override
    public Action getPreferredAction() {
        return getActions(false)[0];
    }

    /** Specifying what should happen when the user invokes the Open action */
    private static class EntryOpenCookie implements <a href="http://bits.netbeans.org/dev/javadoc/org-openide-nodes/org/openide/cookies/OpenCookie.html">OpenCookie</a> {

        private final SyndEntry entry;

        EntryOpenCookie(SyndEntry entry) {
            this.entry = entry;
        }

        @Override
        public void open() {
            try {
                URLDisplayer.getDefault().showURL(new URL(entry.getUri()));
            } catch (MalformedURLException mue) {
                Exceptions.printStackTrace(mue);
            }
        }

    }

}</pre>

                    <p class="tips">Above, you use the NetBeans <tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/HtmlBrowser.URLDisplayer.html">URLDisplayer</a></tt> class to open an entry
                        in the Swing browser. See the completed sample (referred to in
                        the Troubleshooting section below) for code that lets you
                        create your own TopComponent, containing a JEditorPane for
                        displaying your entries.</p>
                </li>
            </ol>
            <h3>Localizing the RssNode Class</h3>

            <ol>
                <li>
                    Open the <tt>FeedReader</tt>
                    module's <tt>Bundle.properties</tt>
                    file.</li>
                <li>
                    Add the following key-value pairs:

                    <pre class="examplecode">FN_title=RSS/Atom Feeds
FN_addbutton=Add
FN_askurl_title=New Feed
FN_askurl_msg=Enter the URL of an RSS/Atom Feed
FN_askurl_err=Invalid URL: {0}|
FN_askfolder_msg=Enter the folder name
FN_askfolder_title=New Folder</pre>

                </li>
            </ol>

            <p>Here is an explanation of the new key-value pairs, which localize strings defined
                in <tt>RssNode.java</tt>:</p>
            <ul>
                <li>
                    <b>
                        FN_title.</b>
                    Localizes the label of the highest node in the Feed Window.</li>
            </ul>

            <p>Localization of user interface for adding a feed:</p>
            <ul>
                <li>
                    <b>
                        FN_addbutton.</b>
                    Localizes the label of the Add menu item that appears in the highest node's pop-up.</li>
                <li>
                    <b>
                        FN_askurl_title.</b>
                    Localizes the title of the New Feed dialog box.</li>
                <li>
                    <b>
                        FN_askurl_msg.</b>
                    Localizes the message that appears in the New Feed dialog box.</li>
                <li>
                    <b>
                        FN_askurl_err.</b>
                    Localizes the error string that is displayed if the URL is invalid.</li>
            </ul>
        </div>
        <h2><a name="running"></a>Run the Application</h2>
        <p>
            Right-click the application and choose Run. You should see the application shown at the start of this tutorial:</p>

        <p><img alt="completed app" src="../../images/tutorials/feedreader/70/feedreader.png"/></p>

        <h2><a name="troubleshooting"></a>Troubleshooting</h2>
        <p>
            If you encounter problems during this tutorial, get the completed sample
            here, in the New Project wizard (Ctrl-Shift-N):</p>

        <p><img alt="sample" src="../../images/tutorials/feedreader/70/sample.png"/></p>

        <!--     <p><b>Note:</b> The completed sample provided by the New Project wizard, above,
                  is slightly different to the code used in this tutorial. Though the end
                   result is the same to the user of the application, the source code
                   in the completed sample is different mainly in that its Nodes extend
                   the FilterNode class,
                   rather than the AbstractNode class used throughout this tutorial.</p>
        -->
        <div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans Platform 7.1 Feed Reader Tutorial">Send Us Your Feedback</a>
            <br style="clear:both;" /></div>
    </body>
</html>
