NetBeans IDE 5.0 FeedReader Tutorial

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 26

NetBeans IDE 5.

0 FeedReader Tutorial

Welcome to the NetBeans IDE 5.0 FeedReader tutorial. The FeedReader application that you
build 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. As an example, here a feed entry from the PlanetNetBeans
RSS feed is opened in the IDE's internal browser:

NetBeans IDE 5.0 FeedReader Tutorial 1


NetBeans IDE 5.0 FeedReader Tutorial

Table of Contents
Introduction
■ About Frequently Used Terms
■ About the FeedReader Application
■ About this Tutorial
■ About the Resources

Playing with the Application


■ Installing the Application
■ Introducing the Application
■ Introducing the Sources

Setting Up the Application


■ Creating the Module Suite Project
■ Wrapping the Libraries
■ Creating the Module Project

Creating the FeedReader Window

Trying Out the Application

Adding Code to the Application


■ Specifying the Application’s Dependencies
■ Creating the RssFeeds Folder
■ Creating the Feed Object
■ Extending the Feed Window
■ Creating the RssNode Class
■ Localizing the RssNode Class

Branding the Application

Distributing the Application

Introduction
Before beginning to code the FeedReader application, it’s a good idea to familiarize yourself
with some of the frequently used terms in the area of application development in NetBeans
IDE. In the process, you will build a general understanding of the application that you will
create, find out about what you are about to learn, and set up everything that you are going
to need.

2 NetBeans IDE 5.0 FeedReader Tutorial


NetBeans IDE 5.0 FeedReader Tutorial

About Frequently Used Terms


This tutorial assumes that you have a basic conceptual understanding of the infrastructure
that is built right into NetBeans. There is less to understand than you might think.
Common terms to be familiar with are as follows:
■ NetBeans Platform. The application framework that provides everything most
desktop applications need and nothing superfluous. The NetBeans Platform provides
an application’s common requirements, such as standard menus, toolbars, document
management, and settings, right out-of-the-box. Building an application “on top of
NetBeans” means that, instead of writing applications from scratch, you only provide
the parts of your application that the NetBeans Platform does not already have. And
you exclude the parts of the NetBeans Platform that you do not need. At the end of the
development cycle, you bundle your application with the NetBeans Platform, but with
your own executable and splash screen. Doing so saves you a lot of time and energy
and results in a solid, reliable application.
■ System Filesystem. The general registry that contains NetBeans configuration
information, built from the layer.xml configuration files of the registered modules.
NetBeans stores a wide variety of configuration information in the System Filesystem.
For example, the System Filesystem contains a folder called Menu, which contains
subfolders with names such as File and Edit. These subfolders contain files that
represent Java classes which implement the actions that appear in the "File" and "Edit"
menus in the IDE.
■ Plug-in Module. A group of Java classes that provides an application with a specific
feature. For example, the feature provided by the Java classes in the plug-in module
that you build in this tutorial is an RSS/Atom feed reader. The Java classes use the
manifest.mf file to declare the module and the layer.xml configuration file to register
their functionality in the System Filesystem.
As an aside: in NetBeans terminology, “plug-in” is an adjective while “module” is a
noun. There is no semantic difference between them.
■ NetBeans APIs. The public interfaces and classes which are available to plug-in
module writers and application writers. They are divided into specific APIs for dealing
with different types of functionality. The contents and behavior of the Java source
packages and their subpackages, as specified in the API reference documentation, are
the APIs. For the full NetBeans API List, click here.
■ Module Suite. A group of interdependent plug-in modules that are deployed together.
The IDE helps you to brand the suite -- for example, you can add a splash screen and
you can specify the parts of the NetBeans Platform that you don’t want your
application to provide.

NetBeans IDE 5.0 FeedReader Tutorial 3


NetBeans IDE 5.0 FeedReader Tutorial

About the FeedReader Application


While writing the FeedReader application, you will leverage a lot of the NetBeans
infrastructure. The first piece you leverage is the System Filesystem. As pointed out
earlier, the System Filesystem consists of configuration data: it is built from the
configuration files (each of which is stored on disk as “layer.xml” files) of all the plug-in
modules in the system, which it writes into the user's settings directory.
The System Filesystem uses the same infrastructure for recognizing files that is used for
recognizing a user's files on disk. That means you can show a view of a folder inside the
configuration data of the IDE just as easily as you can show a folder on disk. This way
you can use all of the plumbing that is built into NetBeans for viewing files and showing
trees and so forth. In fact, many views you see in the IDE use the same technique. For
example, the Favorites window is a view of a folder in the System Filesystem, which
contains links to files on disk. The contents of the Runtime window are also a view of a
folder in the System Filesystem, which is why plug-in modules are able to add nodes to it.
Since it uses the same mechanisms as are used for recognizing files on disk, the objects
inside a folder can have whatever icons and display names you choose to give them.
The other piece you use is the Nodes API. The Nodes API is a generalization of
TreeNode, though Nodes can be displayed in a variety of viewer components, not just
trees. Nodes typically represent DataObjects. A DataObject is basically a parsed file, in
other words, a Java object that knows the meaning of what is in a file or what the file
represents and can do something with it. Nodes add features to DataObjects that the user
interacts with, such as actions, localized display names, and icons.
So, after using wizards to generate some basic templates, you will use the layer.xml file
to create a folder in the System Filesystem for RSS feed objects (here). Next, you will
provide a view of the folder, similar to the IDE's Projects window or Files window, by
building on top of one of the generated files (here). The view is rooted in your folder for
RSS feed objects. Then you get the DataObject representing that folder, and its Node. You
will wrap that node in a FilterNode (here). A FilterNode is a node that can act as a
wrapper for another node; by default it behaves exactly as the other node does, but you
can override methods on it to change things, so that you can give it your own icon,
display name and actions. Then you wrap each of the node's children as well, doing the
same thing for them as for the node.
Next, you will create an Add Feed action on the root node. When the user adds an RSS
feed, you do something very simple: you create a new Feed object (really just an object
that contains the URL, here) and then serialize that Feed object as a file in your RSSFeeds
folder. Since you're using NetBeans built-in infrastructure for visualizing files (because
you're just getting the standard node for the folder, which can notice when files are added
or removed), in a split second the node for the newly added feed will appear in the user
interface. Using the System Filesystem this way means that the amount of code you have
to write to save the list of RSS feeds on exit is... none at all! You save a feed when the
user creates it, and that data is persisted to disk automatically. So, basically, you are just
dropping Feed POJOs into a folder, and you happen to be showing a view of that folder.
The system takes care of virtually everything else.

4 NetBeans IDE 5.0 FeedReader Tutorial


NetBeans IDE 5.0 FeedReader Tutorial

About this Tutorial


This tutorial intends to teach you the following:
■ Creating an application on top of the NetBeans Platform, using wizards and other
facilities provided by NetBeans IDE 5.0.
■ Creating a skeleton windowing component and a skeleton menu item, using wizards in
NetBeans IDE 5.0.
■ Using the NetBeans Nodes API to create nodes for feeds and feed entries.
■ Registering the application in the NetBeans System Filesystem.
■ Branding the application with items such as your own splash screen and titlebar.
■ Providing a distribution of the application.
Once the software is installed, this tutorial can be completed in 60 minutes.

About the Resources


Before you begin, you need to install the following resources on your computer:
■ NetBeans IDE 5.0 (download)
■ Java Standard Development Kit (JDK) 1.4.2 (download) or 5.0 (download)
■ Rss and atOM utilitiEs (download)
■ Rome Fetcher (download)
■ JDom (download)
■ FeedReader icon and splash screen (download). You can put the icon and splash screen
anywhere in your filesystem. Later in this tutorial you will be shown how to include
them in your NetBeans project folder.

Playing with the Application


Before you start writing the application, you might want to acquaint yourself with the final
product. Fortunately, the FeedReader application is an official NetBeans sample, bundled
with the IDE, and waiting for you to pull it from the New Project wizard.

Installing the Application


Take the following steps to install the sample:

1. Start the IDE.

2. Choose File > New Project (Ctrl-Shift-N), then expand Samples, then select NetBeans
Plug-in Modules, and choose FeedReader. Click Next.

NetBeans IDE 5.0 FeedReader Tutorial 5


NetBeans IDE 5.0 FeedReader Tutorial

3. Name the project whatever you like, choose a location to store your project, and click
Finish. The IDE opens the FeedReader sample.

4. Right-click the FeedReader Application project node and choose Run Project. The
application starts up. During installation, notice that a splash screen is displayed.

Introducing the Application


The FeedReader application displays the RSS/Atom Feeds window, containing a node
called RSS/Atom Feeds.

1. Right-click RSS/Atom Feeds node, choose Add, and enter a URL to an RSS/Atom
feed. For example, enter the NetBeans.org RSS feed (http://www.netbeans.org/rss-
091.xml) or the PlanetNetBeans RSS feed (http://www.planetnetbeans.org/rss20.xml).

2. Click OK. A node is added for the feed; its children are the feed entries. Normally,
feed entries are articles or topics that the feed makes available.

3. Repeat the process and add more feeds.

4. Double-click a feed entry to open it in the IDE’s default browser.


Other functionality provided by the rich-client application:
■ Right-click a node and choose Add Folder to create a new folder, which you can use to
organize your feeds.
■ Right-click a feed and choose Delete to remove a feed.
■ Right-click a feed entry and choose Open to open it in the editor pane.

Introducing the Sources


The FeedReader sample consists of main files (Java classes) and supporting files.
Main files:
■ Feed.java
Encapsulates a URL and its associated Rome feed.
■ FeedAction.java
Defines the action that appears in the Window menu with the label Open Feed
Window. It opens the Feed Window.
■ FeedTopComponent.java
Defines the action that appears in the Window menu with the label Open Feed
Window. It opens the Feed Window.
■ RssNode.java
Node class for the RSS feeds folder and its children. Note that mainly you proxy the
actual DataNode/DataFolder for the RssFeeds folder in the System Filesystem. This

6 NetBeans IDE 5.0 FeedReader Tutorial


NetBeans IDE 5.0 FeedReader Tutorial

gives you a lot of functionality for free, like the ability to delete, listening for changes,
etc. So when you add a new RSS feed, all you do is create a new Feed object and
serialize it into that folder.
Supporting files:
■ build.xml
Provides Ant targets for common tasks, such as building and running the application.
■ Bundle.properties
Localization key-value pairs.
■ FeedTopComponentSettings.xml
Specifies all the interfaces of the FeedReader application.
■ FeedTopComponentWstcref.xml
Specifies a reference to the component.
■ layer.xml
Registers folders and files in the System Filesystem. You will be shown how to use the
System Filesystem Browser to work with this file.
■ project.xml
Declares project metadata, such as module dependencies. You will be shown how to
use the Project Properties dialog box to work with this file.
■ rss16.gif
Icon displayed by the application's menu item and in its Help > About dialog box.
■ splash.gif
Splash screen.

Setting Up the Application


In NetBeans IDE, building an application on top of NetBeans starts with generating a large
number of files which will serve as the foundation of your application. For example, the IDE
provides a Module Project wizard, a Module Suite Project wizard, and a Library Wrapper
Module Project wizard that set up all the basic files needed by plug-in modules and
applications built on the NetBeans Platform.
■ Module Suite Project. 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.
■ Library Wrapper Module Project. 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.
■ Module Project. A project for implementing the functionality, business logic, and user
interface of a plug-in module or application built on the NetBeans Platform.

NetBeans IDE 5.0 FeedReader Tutorial 7


NetBeans IDE 5.0 FeedReader Tutorial

Creating the Module Suite Project


1. Choose File > New Project (Ctrl-Shift-N). Under Categories, select NetBeans Plug-in
Modules. Under projects, select Module Suite Project. Click Next.

2. In the Name and Location panel, type feedreader-suite in Project Name. Change the
Project Location to any directory on your computer, such as c:\mymodules. Click
Finish.
The IDE creates the feedreader-suite project. The project will contain the module project
and library wrapper module projects that you will create in the following subsections.
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).

Wrapping the Libraries


You could bundle the entire FeedReader application into a single plug-in module.
However, the application needs the Rome, Rome Fetcher, and JDom libraries:
■ Rome. Reads RSS and Atom feeds, using a very simple API.
■ Rome Fetcher. Allows the retrieval of feeds via HTTP.
■ JDom. Is an XML parsing API. The only reason FeedReader needs it is because the
Rome library uses it.
Later, if you want to extend the FeedReader 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 FeedReader. 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.

1. Choose File > New Project (Ctrl-Shift-N). Under Categories, select NetBeans Plug-in
Modules. Under projects, select Library Wrapper Module Project. Click Next.

2. In the Select Library panel, browse to the folder where you downloaded JDom, and
then select jdom.jar and LICENSE.txt. Click Next.

3. In the Name and Location panel, accept all the defaults. Note that the library wrapper
module project will be housed within the module suite project. You could also house it
somewhere else, but for versioning purposes it is a good idea to put it within the
module suite project. Also note that the feedreader-suite module suite project is
selected in the Add to Module Suite drop-down. Click Next.

4. In the Basic Module Configuration panel, accept all the defaults. Click Finish. The
new library wrapper module project opens in the IDE and displays in the Projects
window.

5. Create a library wrapper module project for Rome. Accept all the defaults.

8 NetBeans IDE 5.0 FeedReader Tutorial


NetBeans IDE 5.0 FeedReader Tutorial

6. Create a library wrapper module project for Rome Fetcher.


You now have a library wrapper module project containing the JDom JAR file and two
other library wrapper module projects containing the Rome and Rome Fetcher JAR files.

Creating the Module Project


1. Choose File > New Project (Ctrl-Shift-N). Under Categories, select NetBeans Plug-in
Modules. Under projects, select Module Project. Click Next.

2. In the Name and Location panel, type FeedReader in Project Name. Accept all the
defaults. Click Next.

3. In the Basic Module Configuration panel, replace yourorghere in Code Name Base
with myorg, so that the whole code name base is org.myorg.feedreader. Leave the
location of the localizing bundle and XML layer, so that they will be stored in a
package with the name org/myorg/feedreader. Click Finish.

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:

Right-click the feedreader-suite project node, choose Properties, and click Sources in the
Project Properties dialog box. The panel shows the modules that were added to the module
suite while you were creating their projects. You should see FeedReader, jdom, rome, and rome-
fetcher listed in the Suite Modules list.

Creating the FeedReader Window


In this section you use the Window Component wizard to generate files that create a custom
windowing component and an action to invoke it. The wizard also registers the action as a
menu item in the layer.xml configuration file and adds entries for serializing the windowing
component. Right after finishing this section, you are shown how to try out the files that the
Window Component wizard generates for you.

1. Right-click the FeedReader project node and choose New > File/Folder. Under
Categories, select NetBeans Module Development. Under File Types, select Window
Component. Click Next.

2. In the Basic Settings panel, select explorer in the drop-down list and click Open on
Application Start. Click Next.

3. In the Name and Location panel, type Feed as the Class Name Prefix and browse to the
location where you saved rss16.gif. The GIF file will be shown in the menu item that
invokes the action.

NetBeans IDE 5.0 FeedReader Tutorial 9


NetBeans IDE 5.0 FeedReader Tutorial

4. Click Finish.
The IDE creates the following new files:
■ FeedAction.java. Defines the action that appears in the Window menu with the label
Open Feed Window and the rss16.gif image. It opens the Feed Window.
■ FeedTopComponent.java. Defines the Feed Window.
■ FeedTopComponentSettings.xml. Specifies all the interfaces of the org.myorg.feedreader
rich-client application. Enables easy lookup of instances, without the need to instantiate
each. Avoids the need to load classes or create objects and therefore improves
performance. Registered in the Windows2/Components folder of the layer.xml file.
■ FeedTopComponentWstcref.xml. Specifies a reference to the component. Enables the
component to belong to more than one mode. Registered in the Windows2/Modes
folder of the layer.xml file.
The IDE modifies the following existing files:
■ project.xml. Two module dependencies have been added, Utilities API (click here
for Javadoc) and Window System API (click here for Javadoc).
■ Bundle.properties. Three key-value pairs have been added:

CTL_FeedAction. Localizes the label of the menu item, defined in FeedAction.java.


CTL_FeedTopComponent. Localizes the label of FeedTopComponent.java.
HINT_FeedTopComponent. Localizes the tooltip of FeedTopComponent.java.

■ Finally, three registration entries have been added to the layer.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN"
"http://www.netbeans.org/dtds/filesystem-1_1.dtd">
<filesystem>
<folder name="Actions">
<folder name="Window">
<file name="org-myorg-feedreader-FeedAction.instance"/>
</folder>
</folder>
<folder name="Menu">
<folder name="Window">
<file name="FeedAction.shadow">
<attr name="originalFile" stringvalue=
"Actions/Window/org-myorg-feedreader-FeedAction.instance"/>
</file>
</folder>
</folder>
<folder name="Windows2">
<folder name="Components">
<file name="FeedTopComponent.settings" url=
"FeedTopComponentSettings.xml"/>
</folder>
<folder name="Modes">
<folder name="explorer">

10 NetBeans IDE 5.0 FeedReader Tutorial


NetBeans IDE 5.0 FeedReader Tutorial

<file name="FeedTopComponent.wstcref" url=


"FeedTopComponentWstcref.xml"/
</folder>
</folder>
</folder>
</filesystem>

This is what the entries in the layer.xml file do:


■ <Actions>
Registers the action as an action in the Window folder.
■ <Menu>
Registers the action as a menu item in the Window menu.
■ <Windows2>
Registers the FeedTopComponentSettings.xml, which is used for looking up the
windowing component. Registers the component reference file
FeedTopComponentWstcref.xml in the ‘editor’ window. To dock the component in a
different window, you can manually change ‘explorer’ to one of these values instead:

commonpalette|
editor
properties
leftSlidingSide
rightSlidingSide\
bottomSlidingSide
navigator
debugger
output

Trying Out the Application


Without having typed a single line of code, you can already take your application for a spin.
Trying it out means deploying the application to another instance of your installation of
NetBeans IDE and then checking to see that the empty Feed Window displays correctly.

The IDE uses an Ant build script to build and install your application. The build script was
created for you when you created the module project.

1. In the Projects window, right-click the feedreader-suite project and choose Run. The
application is built and is installed in another instance of your installation of NetBeans
IDE. The IDE opens and displays the new Feed Window.

2. In the IDE’s Window menu, you should see the new menu item.

3. Hover over the window’s label. You should see the hint displayed.

NetBeans IDE 5.0 FeedReader Tutorial 11


NetBeans IDE 5.0 FeedReader Tutorial

4. Click the small cross on the right side of the Feed Window’s label. The window closes.

5. Choose Window > Open Feed Window to reopen the window.

6. From the main menu, choose File > Exit to exit the IDE.

Adding Code to the Application


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. Then, you use the
New File wizard and the Source Editor to create and code the main classes that were
introduced in the Introducing the Sources section.

Specifying the Application’s Dependencies


You need to subclass several classes that belong to the NetBeans APIs. Each has to be
declared as a dependency. Use the Project Properties dialog box for this purpose.

1. In the Projects window, right-click the FeedReader project and choose Properties. In the
Project Properties dialog box, click Libraries. Notice that some APIs have already been
declared as Module Dependencies. This was done for you by the Window Component
wizard.

2. Click Add... at the top of the Libraries panel.

3. Add the following APIs:

Actions API
Datasystems API
Dialogs API
Explorer and Property Sheet API
File System API
Nodes API
rome
rome-fetcher

4. Click OK to exit the Project Properties dialog box.

5. Optionally, in the Projects window, expand the FeedReader module project in the IDE,
expand the Important Files node, double-click Project Metadata so that it opens in the
IDE. Notice that the APIs you selected have been declared as dependencies.

12 NetBeans IDE 5.0 FeedReader Tutorial


NetBeans IDE 5.0 FeedReader Tutorial

6. Next, you need to make Rome dependent on JDom. Right-click the Rome library
wrapper moduleproject in the Projects window and choose Properties. In the Project
Properties dialog box, click Libraries and then click Add next to the Module
Dependencies list. Add JDom. Click OK to exit the Project Properties dialog box.

7. Finally, since Rome Fetcher depends on both Rome and JDom, you need to make
Rome Fetcher dependent on Rome. Because Rome already depends on JDom, you do
not need to make Rome Fetcher dependent on JDom.

8. Optionally, in the Projects window, expand the Rome module in the IDE, expand the
Important Files node, double-click Project Metadata so that it opens in the IDE. Notice
that the Rome JAR files are on the classpath, that JDom is a module dependency, and
that their packages are publicly exposed. You should see the same in Rome Fetcher’s
Project Metadata file.

Creating the RssFeeds Folder


You will use the System Filesystem Browser to add a folder for RSS feed objects. Later,
you will add code to FeedTopComponent.java, which was created for you by the Window
Component wizard, to view the content of the folder.

1. In the Projects window, expand the FeedReader project node, expand the Important
Files node, and then expand the XML Layer node. The System Filesystem Browser
opens. It shows you the following nodes:

<this layer>. The folders provided by the current plug-in module


<this layer in context>. All the folders available in the System Filesystem.

2. Right-click the <this layer> node and choose New > Folder.

3. Type RssFeeds in the New Folder dialog box. Click OK. Double-click the node for the
layer.xml file so that it opens in the Source Editor. Notice that this entry has been
added:

<folder name="RssFeeds"/>

Creating the Feed Object


Next you create a simple POJO that encapsulates a URL and its associated Rome feed.

1. Right-click the FeedReader project node, choose New > File/Folder and then choose the
Java Class file type in the Java Class category. Click Next.

2. Name the class Feed and select org.myorg.feedreader in the Package drop-down. Click
Finish.

NetBeans IDE 5.0 FeedReader Tutorial 13


NetBeans IDE 5.0 FeedReader Tutorial

3. In the Source Editor, replace the default Feed class with the following:
public class Feed implements Serializable {
private static FeedFetcher s_feedFetcher = new HttpURLFeedFetcher(
HashMapFeedInfoCache.getInstance());
private transient SyndFeed m_syndFeed;
private URL m_url;
private String m_name;

protected Feed() {
}

public Feed(String str) throws MalformedURLException


{
m_url = new URL(str);
m_name = str;
}

public URL getURL()


{
return m_url;
}

public SyndFeed getSyndFeed() throws IOException {


if (m_syndFeed == null) {
try {
m_syndFeed = s_feedFetcher.retrieveFeed(m_url);
if (m_syndFeed.getTitle() != null)
m_name = m_syndFeed.getTitle();
} catch(Exception ex) {
throw new IOException(ex.getMessage());
}
}
return m_syndFeed;
}

public String toString(){


return m_name;
}
}
A lot of code is underlined, because you have not declared their packages. You do this in
the next steps.
Take the following steps to reformat the file and declare its dependencies:

1. Press Ctrl-Shift-F to format the code.

2. Press Alt-Shift-F, select java.net.URL, click OK, and the IDE adds the following
import statements below the package statement:

14 NetBeans IDE 5.0 FeedReader Tutorial


NetBeans IDE 5.0 FeedReader Tutorial

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;

All the red underlining should now have disappeared. If not, do not continue with this
tutorial until you have solved the problem.

Extending the Feed Window


1. Double-click FeedTopComponent.java so that it opens in the Source Editor.

2. Type implements ExplorerManager.Provider at the end of the class declaration.

3. Press Alt-Enter in the line and click on the suggestion. The IDE adds an import
statement for the required package org.openide.explorer.ExplorerManager.

4. Press Alt-Enter again and click on the suggestion. The IDE implements the abstract
method getExplorerManager().

5. Type return manager; in the body of the new getExplorerManager() method. Press Alt-
Enter in the line and let the IDE create a field called manager for you. Replace the
default definition with this one:

private final ExplorerManager manager = new ExplorerManager();

6. Right below the field declaration in the previous step, declare this one:

private final BeanTreeView view = new BeanTreeView();

7. Finally, add the following code to the end of the constructor:

setLayout(new BorderLayout());
add(view, BorderLayout.CENTER);
view.setRootVisible(true);
try {
manager.setRootContext(new RssNode.RootRssNode());
} catch (DataObjectNotFoundException ex) {

NetBeans IDE 5.0 FeedReader Tutorial 15


NetBeans IDE 5.0 FeedReader Tutorial

ErrorManager.getDefault().notify(ex);
}
ActionMap map = getActionMap();
map.put("delete", ExplorerUtils.actionDelete(manager, true));
associateLookup(ExplorerUtils.createLookup(manager, map));

Now a lot of code is underlined, because you have not declared their associated packages.
You do this in the next steps.

Take the following steps to reformat the file and declare its dependencies:

1. Press Ctrl-Shift-F to format the code.

2. Press Alt-Shift-F, select org.openide.ErrorManager, click OK, and the IDE adds several
import statements below the package statement. The complete list of import statements
should now be as follows:

import java.awt.BorderLayout;
import java.io.Serializable;
import javax.swing.ActionMap;
import org.openide.ErrorManager;
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerUtils;
import org.openide.explorer.view.BeanTreeView;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;
import org.openide.util.Utilities;
import org.openide.windows.TopComponent;

3. Note that the line manager.setRootContext(new RssNode.RootRssNode()); is still


underlined in red, because you have not created RssNode.java 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.

Creating the RssNode Class


1. Create RssNode.java in the org.myorg.feedreader package.

2. Replace the default class with the following:


class RssNode extends FilterNode {

/** Declaring the children of the root RSS node */


public RssNode(Node folderNode) throws DataObjectNotFoundException

16 NetBeans IDE 5.0 FeedReader Tutorial


NetBeans IDE 5.0 FeedReader Tutorial

{
super(folderNode, new RssFolderChildren(folderNode));
}
/** Declaring the Add Feed action and Add Folder action */
public Action[] getActions(boolean popup) {
DataFolder df =
(DataFolder)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(
Repository.getDefault().getDefaultFileSystem()

.getRoot().getFileObject("RssFeeds")).getNodeDelegate());
}
public String getDisplayName() {
return NbBundle.getMessage(RssNode.class, "FN_title");
}
}

/** Getting the children of the root node */


private static class RssFolderChildren extends FilterNode.Children
{
RssFolderChildren(Node rssFolderNode) {
super(rssFolderNode);
}
protected Node[] createNodes(Object key) {
Node n = (Node) key;
try {
if (n.getLookup().lookup(DataFolder.class) != null)
{
return new Node[] { new RssNode(n) };
} else {
Feed feed = getFeed(n);
if (feed != null) {
return new Node[] { new OneFeedNode(n,
feed.getSyndFeed()) };
} else {
// best effort
return new Node[] { new FilterNode(n) };
}
}
} catch (IOException ioe) {
ErrorManager.getDefault().notify(ioe);
} catch (IntrospectionException exc) {

NetBeans IDE 5.0 FeedReader Tutorial 17


NetBeans IDE 5.0 FeedReader Tutorial

ErrorManager.getDefault().notify(exc);
}
// Some other type of Node (gotta do something)
return new Node[] { new FilterNode(n) };
}
}

/** Getting the feed node and wrapping it in a FilterNode */


private static class OneFeedNode extends FilterNode {
OneFeedNode(Node feedFileNode, SyndFeed feed) throws
IOException, IntrospectionException {
super(feedFileNode,
new FeedChildren(feed),
new ProxyLookup(new Lookup[] {
Lookups.fixed(new Object[] { feed }),
feedFileNode.getLookup() }));
}

public String getDisplayName() {


SyndFeed feed = (SyndFeed)
getLookup().lookup(SyndFeed.class);
return feed.getTitle();
}

public Image getIcon(int type) {


return
Utilities.loadImage("org/myorg/feedreader/rss16.gif");
}

public Image getOpenedIcon(int type) {


return getIcon(0);
}
public Action[] getActions(boolean context) {
return new Action[] {
SystemAction.get(DeleteAction.class) };
}
}

/** Defining the children of a feed node */


private static class FeedChildren extends Children.Keys {
private final SyndFeed feed;
public FeedChildren(SyndFeed feed) {
this.feed = feed;
}

protected void addNotify() {


setKeys(feed.getEntries());
}

18 NetBeans IDE 5.0 FeedReader Tutorial


NetBeans IDE 5.0 FeedReader Tutorial

public Node[] createNodes(Object key) {


try {
return new Node[] { new EntryBeanNode((SyndEntry)
key) };
} catch (final IntrospectionException ex) {

ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
//Should never happen - no reason for it to fail abov
return new Node[] { new AbstractNode(Children.LEAF)
{
public String getHtmlDisplayName() {
return "<font color=’red’>" +
ex.getMessage() + "</font>";
}
}};
}
}
}

/** Wrapping the children in a FilterNode */


private static class EntryBeanNode extends FilterNode {
private SyndEntry entry;
public EntryBeanNode(SyndEntry entry) throws
IntrospectionException {
super(new BeanNode(entry), Children.LEAF,
Lookups.fixed(new Object[] { entry, new EntryOpenCookie(entry) }));
this.entry = entry;
}

/** Using HtmlDisplayName ensures any HTML in RSS entry titles


are
/**properly handled, escaped, entities resolved, etc. */
public String getHtmlDisplayName() {
return entry.getTitle();
}

/** Making a tooltip out of the entry’s description */


public String getShortDescription() {
return entry.getDescription().getValue();
}

/** Providing the Open action on a feed entry */


public Action[] getActions(boolean popup) {
return new Action[] { SystemAction.get(OpenAction.class)
};
}

public Action getPreferredAction() {


return (SystemAction) getActions(false) [0];

NetBeans IDE 5.0 FeedReader Tutorial 19


NetBeans IDE 5.0 FeedReader Tutorial

}
}

/** Specifying what should happen when the user invokes the Open
action */
private static class EntryOpenCookie implements OpenCookie {
private final SyndEntry entry;
EntryOpenCookie(SyndEntry entry) {
this.entry = entry;
}

public void open() {


try {
URLDisplayer.getDefault().showURL(new
URL(entry.getUri()));
} catch (MalformedURLException mue) {
ErrorManager.getDefault().notify(mue);
}
}
}

/** Looking up a feed */


private static Feed getFeed(Node node) {
InstanceCookie ck = (InstanceCookie)
node.getCookie(InstanceCookie.class);
if (ck == null) {
throw new IllegalStateException("Bogus file in feeds
folder: " + node.getLookup().lookup(FileObject.class));
}
try {
return (Feed) ck.instanceCreate();
} catch (ClassNotFoundException ex) {
ErrorManager.getDefault().notify(ex);
} catch (IOException ex) {
ErrorManager.getDefault().notify(ex);
}
return null;
}

/** Creating an action for adding a folder to organize feeds into


groups */
private static class AddFolderAction extends AbstractAction {
private DataFolder folder;
public AddFolderAction(DataFolder df) {
folder = df;
putValue(Action.NAME,
NbBundle.getMessage(RssNode.class, "FN_addfolderbutton"));
}
public void actionPerformed(ActionEvent ae) {

20 NetBeans IDE 5.0 FeedReader Tutorial


NetBeans IDE 5.0 FeedReader Tutorial

NotifyDescriptor.InputLine nd = new
NotifyDescriptor.InputLine(
NbBundle.getMessage(RssNode.class,
"FN_askfolder_msg"), //NOI18N
NbBundle.getMessage(RssNode.class,
"FN_askfolder_title"), //NOI18N
NotifyDescriptor.OK_CANCEL_OPTION,
NotifyDescriptor.PLAIN_MESSAGE);
Object result = DialogDisplayer.getDefault().notify(nd);
if (result.equals(NotifyDescriptor.OK_OPTION)) {
final String folderString = nd.getInputText();
try {
DataFolder.create(folder, folderString);
} catch (IOException ex) {
ErrorManager.getDefault().notify(ex);
}
}
}
}

/** Creating an action for adding a feed */


private static class AddRssAction extends AbstractAction {
private DataFolder folder;
public AddRssAction(DataFolder df) {
folder = df;
putValue(Action.NAME,
NbBundle.getMessage(RssNode.class, "FN_addbutton"));
}
public void actionPerformed(ActionEvent ae) {
NotifyDescriptor.InputLine nd = new
NotifyDescriptor.InputLine(
NbBundle.getMessage(RssNode.class,
"FN_askurl_msg"), //NOI18N
NbBundle.getMessage(RssNode.class,
"FN_askurl_title"), //NOI18N
NotifyDescriptor.OK_CANCEL_OPTION,
NotifyDescriptor.PLAIN_MESSAGE);
Object result = DialogDisplayer.getDefault().notify(nd);
if (result.equals(NotifyDescriptor.OK_OPTION)) {
final String urlString = nd.getInputText();
try {
Feed f = new Feed(urlString);
FileObject fld = folder.getPrimaryFile();
String baseName = "RssFeed"; //NOI18N
int ix = 1;
while (fld.getFileObject(baseName + ix, "ser")
!= null) {
ix++;
}

NetBeans IDE 5.0 FeedReader Tutorial 21


NetBeans IDE 5.0 FeedReader Tutorial

FileLock lock = null;


try {
FileObject writeTo =
fld.createData(baseName + ix, "ser");
lock = writeTo.lock();
ObjectOutputStream str = new
ObjectOutputStream(writeTo.getOutputStream(lock));
str.writeObject(f);
} catch (IOException ioe) {
ErrorManager.getDefault().notify(ioe);
} finally {
if (lock != null)
lock.releaseLock();
}
} catch (MalformedURLException ex) {
IllegalArgumentException iae = new
IllegalArgumentException(NbBundle.getMessage(RssNode.class,
"FN_askurl_err", urlString), ex); //NOI18N
throw iae;
}
}
}
}
}

A lot of code is underlined, because you have not declared their packages. You do this in
the next step. Now take the following steps to reformat the file and declare its
dependencies:

1. Press Ctrl-Shift-F to format the code.

2. Press Alt-Shift-F and select the following import statements:

org.openide.actions.OpenAction
javax.swing.Action
org.openide.nodes.Children
org.openide.filesystems.FileLock
java.awt.Image
org.openide.nodes.Node
org.openide.ErrorManager
org.openide.util.Utilities
java.net.URL
org.openide.filesystems.Repository
java.beans.IntrospectionException

22 NetBeans IDE 5.0 FeedReader Tutorial


NetBeans IDE 5.0 FeedReader Tutorial

3. Click OK, and the IDE adds a lot of import statements below the package statement.
All red underlining should now have disappeared. If not, do not continue with this
tutorial until you have solved the problem.

Localizing the RssNode Class


1. Open the FeedReader module’s Bundle.properties file.

2. Add the following key-value pairs:

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_addfolderbutton=Add Folder
FN_askfolder_msg=Enter the folder name
FN_askfolder_title=New Folder

Here is an explanation of the new key-value pairs, which localize strings defined in
RssNode.java:

■ FN_title. Localizes the label of the highest node in the Feed Window.
Localization of user interface for adding a feed:
■ FN_addbutton. Localizes the label of the Add menu item that appears in the highest
node’s pop-up.
■ FN_askurl_title. Localizes the title of the New Feed dialog box.
■ FN_askurl_msg. Localizes the message that appears in the New Feed dialog box.
■ FN_askurl_err. Localizes the error string that is displayed if the URL is invalid.
Localization of user interface for adding a folder:
■ FN_addfolderbutton. Localizes the label of the Add Folder menu item that appears
in the highest node’s pop-up.
■ FN_askfolder_msg. Localizes the message that appears in the Add Folder dialog
box.
■ FN_askfolder_title. Localizes the title of the Add Folder dialog box.

Branding the Application


Now that you are at the end of the development cycle, while you are wrapping up the
application, you are concerned with the following questions:

NetBeans IDE 5.0 FeedReader Tutorial 23


NetBeans IDE 5.0 FeedReader Tutorial

■ What should the name of the application’s executable be?


■ What should the user see when starting up my application? A progress bar? A splash
screen? Both?
■ When my application starts up, what should be displayed in the title bar?
■ Do I need all the menus and toolbar buttons that the NetBeans Platform provides by
default?

These questions relate to branding, the activity of personalizing an application built on top of
the NetBeans Platform. The IDE provides a panelin the Project Properties dialog box of
module suite projects to help you with branding.

1. Right-click the feedreader-suite project node (not the FeedReader project node) and
choose Properties. In the Project Properties dialog box, click Application.

2. In the Application panel, click Create Standalone Application. The IDE prompts you to
exclude the IDE-related modules. Click Exclude, because the FeedReader application
will not need IDE-related modules, such as those that provide the Source Editor in
NetBeans IDE.

3. Type feedreader in Branding Name. Type Feed Reader Application in Application


Title. The value in branding name sets the executable’s name, while the value in
application title sets the application’s title bar.

4. Click Browse to browse to the rss16.gif icon. The icon will be displayed in the Help
> About dialog box.

5. In the Splash Screen panel, click Browse to browse to splash.gif. Optionally, change
the color and text size of the progress bar. Or, if you do not want a progress bar,
unselect Enabled.

6. Click OK.
The branding folder is created in the FeedReader Application project. It is visible in the
Files window (Ctrl-2).

7. In the Files window, expand the FeedReader Application project node. Then continue
expanding nodes until you find this one:
branding/modules/org-netbeans-core-window.jar/org/netbeans/core/windows

8. Right-click the node, choose New > File/Folder, and select Folder in the Other
category. Click Next and name the folder resources. Click Finish.

9. Right-click the new resources node, choose New > File/Folder, and select XML
Document in the XML category. Click Next. Name the file layer. Click Next and then
click Finish. Replace the content of the new layer.xml file with the following:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN"
"http://www.netbeans.org/dtds/filesystem-1_1.dtd">
<!--
This is a ‘branding’ layer. It gets merged with the layer file it’s branding.
In this case, it’s just hiding menu items and toolbars we don’t want.

24 NetBeans IDE 5.0 FeedReader Tutorial


NetBeans IDE 5.0 FeedReader Tutorial

-->
<filesystem>

<!-- hide unused toolbars -->


<folder name="Toolbars">
<folder name="File_hidden"/>
<folder name="Edit_hidden"/>
</folder>

<folder name="Menu">
<folder name="File">
<file name="org-openide-actions-
SaveAction.instance_hidden"/>
<file name="org-openide-actions-
SaveAllAction.instance_hidden"/>
<file name="org-netbeans-core-actions-
RefreshAllFilesystemsAction.instance_hidden"/>
<file name="org-openide-actions-
PageSetupAction.instance_hidden"/>
<file name="org-openide-actions-
PrintAction.instance_hidden"/>
</folder>
<folder name="Edit_hidden"/>
<folder name="Tools_hidden"/>
</folder>

</filesystem>

Distributing the Application


The IDE uses an Ant build script to create a distribution of your application. The build script
is created for you when you create the project.

1. In the Projects window, right-click the FeedReader Application project node and choose
Build ZIP Distribution. The Output window shows you where the ZIP distribution is
created.

2. In your filesystem, find the feedreader.zip distribution in the dist folder in your
project directory. Unzip it. Launch the application, which you will find in the bin
folder. During start up, the splash screen is displayed. When the application has started
up, go to the Help > About dialog box and notice the icon and splash screen that you
specified in the Branding the Application section.

When it is up and running, the FeedReader application displays the RSS/Atom Feeds
window, containing a node called RSS/Atom Feeds. See Playing with the Application for
details.

Congratulations! You have completed the FeedReader tutorial.

NetBeans IDE 5.0 FeedReader Tutorial 25


NetBeans IDE 5.0 FeedReader Tutorial

26 NetBeans IDE 5.0 FeedReader Tutorial

You might also like