<!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="71/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>
            <div class="indent">
                <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>
            </div>

            <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>
            <div class="indent">
                <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>
            </div>

            <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>
            <div class="indent">
                <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>
            </div>
            <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>
            <div class="indent">
                <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>
            </div>

            <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>
            <div class="indent">
                <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>
            </div>
            <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>
            <div class="indent">
                <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>
            </div>
            <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>
            <div class="indent">
                <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>
            </div>
            <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>
            <div class="indent">
                <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>
            </div>
            <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>
            <div class="indent">
                <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>
            </div>
            <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>
            <div class="indent">
                <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>
            </div>
            <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>
            <div class="indent">
                <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>
            </div>
            <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>
            <div class="indent">
                <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>
            </div>

            <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>
            <div class="indent">
                <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>
            </div>
            <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>
            <div class="indent">
                <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>
            </div>
            <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>
            <div class="indent">
                <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>
            </div>
            <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>
            <div class="indent">
                <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>
            </div>
            <h3>Localizing the RssNode Class</h3>
            <div class="indent">
                <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>
            </div>
            <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>
