From the developer standpoint, the automated help component, or help system, is often the last consideration when building a Java application. For users, however, the help system is an invaluable asset when learning a new application. As the demand for more full-featured and reliable application help systems has increased, so has the time and productivity burden on application developers. Fortunately, the Java platform includes an API just for building application help systems.
In this article, you'll learn how to use the JavaHelp 2.0 API to build a standard, full-featured help system for a simple Java application. You'll start by building a basic application help system that includes a set of topic files, a set of navigation files, and a set of data files. You'll then learn how to make the help system accessible from your Java application and customize it with text- or image-based navigation, pre-set fonts, layered presentation windows, and a searchable database. You'll also learn how to implement context-sensitive features, embed the help system directly into your application, merge multiple help systems into one, and create custom lightweight components for your help system. I'll conclude the article with a quick tour of JavaHelp 2.0's server-side help system framework.
Note: This article assumes you are familiar with the design considerations of building a help system and with enterprise application development on the Java platform. Some experience with Swing GUI development will also be helpful.
In this article, you'll build a JavaHelp system for a Tax Calculator
application. The Tax Calculator is shown in Figure 1. You'll find the
example source code in the Resources section at
the end of the article. Locate the Tax Calculator by running
FirstLook.
Figure 1. The Tax Calculator's About page

In Figure 2 you can see the navigational setup for the Tax Calculator help system. Note that some of the icons used for navigation have been highlighted for later discussion.
Figure 2. Navigating the help system

Each JavaHelp help system contains a set of files called the HelpSet. Together, these files provide the foundation of a working application help system. The JavaHelp HelpSet includes three types of files:
- HelpSet data files
- Navigation files
- Topic files
You'll find the HelpSet files for the example Tax Calculator help system in the Resources section. The HelpSet data files are TaxCalculatorHelpSet.hs and TaxCalculatorMap.jhm. The navigation files are TaxCalculatorIndex.xml, TaxCalculatorTOC.xml, and TaxCalculatorGlossary.xml. The topic files reside in the folder TaxCalculator. Please use these files to follow the discussion in the sections that follow.
There are two HelpSet data files named the helpset file and the map file, respectively.The helpset file is the master control file for your help system. It must have the file extension .hs. The map file is used to associate a map ID to each help topic for navigational purposes. The map file has the file extension .jhm. I'll go over each HelpSet file type in detail.
The helpset file
The helpset file provides the foundation of a working application help system.
A typical helpset file has a structure like the one in Listing 1.
Listing 1. The helpset file
<helpset version="2.0">
<!-- maps section -->
<maps>...</maps>
<!-- views section -->
<view>...</view>
...
<!-- presentation section -->
<presentation>...</presentation>
<!-- implementation section -->
<impl>...</impl>
</helpset>
|
You'll note that the typical helpset file has four sections: the maps section, the views section, the presentation section, and the implementation section. When a user accesses your help system, the system starts by reading the .hs file. It uses the map file specified in the maps section to find the needed topic files, the navigation files found in the views section to create navigation views, and so on. I'll use the Tax Calculator help system as an example to show how the four sections of the helpset file actually work together.
The maps section
The <maps> element specifies the map file, which I'll
discuss further below. Listing 2 shows the maps section for TaxCalculatorHelpSet.hs. Note that TaxCalculatorMap.jhm is the map file. It resides in the same directory as TaxCalculatorHelpSet.hs.
Listing 2. The maps section
<maps>
<homeID>overview</homeID>
<mapref location="TaxCalculatorMap.jhm" />
</maps>
|
The views section
The helpset file can specify one or more <view> elements,
which specify the help system's navigation views along with their
navigation files. Navigation views are displayed in the navigation pane
(see Figure 2). When setting up your help system,
you can choose from the following views:
javax.help.GlossaryViewjavax.help.TOCViewjavax.help.IndexViewjavax.help.FavoritesViewjavax.help.SearchView
Listing 3 specifies a Glossary view and the location of its navigation file.
Listing 3. A Glossary view element
<view>
<name>Glossary</name>
<label>Glossary</label>
<type>javax.help.GlossaryView</type>
<data>TaxCalculatorGlossary.xml</data>
<image>glossary_icon</image>
</view>
|
You can use anything you like as the <name> and <label> for a view. The <type> element specifies the navigational
view for your help system, and the <data> element specifies the path to the
navigation file. If you specify the <image> element, the image will be displayed
at the top of navigation pane as the tab icon for this view (as shown in
Figure 2, part 3). The element value glossary_icon is defined in the map file (see Listing 6).
The presentation section
The <presentation> element defines the help window
properties, as shown in Listing 4.
Listing 4. The presentation section
<presentation default="true">
<name>Main_Window</name>
<size width="640" height="480" />
<location x="0" y="0" />
<title>Tax Calculator</title>
<image>icon</image>
<toolbar>
<helpaction>javax.help.BackAction</helpaction>
<helpaction image="addfav_icon">javax.help.FavoritesAction</helpaction>
</toolbar>
</presentation>
|
The value of element <name> --
Main_Window -- can be called in Java code.
You will use the <title> element to
specify the title of the help window, and the <image> element to specify a title-bar icon
(see the first panel of Figure 2). Note that icon is defined in the map file below. The <toolbar> element is also configurable. If
you do not specify a value, your help system will include some default
toolbar buttons. Each <helpaction>
corresponds to a toolbar button in the help window toolbar. JavaHelp
provides eight types of helpaction, as
follows:
BackActionForwardActionSeparatorActionHomeActionReloadActionPrintActionPrintSetupActionFavoritesAction
So, referring back to Figure 2, you'll see that the
toolbar buttons are (from left to right): BackAction,
ForwardAction, SeparatorAction, HomeAction, ReloadAction,
SeparatorAction, PrintAction, PrintSetupAction, and FavoritesAction. You can change the icon for the toolbar buttons
by specifying the image attribute of the
<helpaction>
elements. Note that addfav_icon is defined in the map
file below. Setting the default attribute of the
<presentation> tag to true
will make this the default presentation for your help system.
The implementation section
In the <impl> element, you can specify the types of files that can be displayed in the
content viewer. For example, the code in Listing 5 would
enable the user to view HTML and PDF files.
Listing 5. The implementation section
<impl>
<helpsetregistry helpbrokerclass="javax.help.DefaultHelpBroker" />
<viewerregistry viewertype="text/html" viewerclass="com.sun.java.help.impl.CustomKit" />
<viewerregistry viewertype="application/pdf" viewerclass="Your PDF Editor Kit" />
</impl>
|
The map file
The map file is the other file type found in the HelpSet data
files. It associates a map ID to each help topic by mapping the ID
string to the URL of the help topic file. The
helpset file and navigation files always refer to help topics by means
of map IDs. The map file can assign map IDs to any type of file. Listing
6 shows the map file for the Tax Calculator help system.
Listing 6. TaxCalculatorMap.jhm
<map version="2.0">
...
<mapID target="overview" url="TaxCalculator/overview.htm" />
<mapID target="icon" url="images/icon.gif" />
<mapID target="glossary_icon" url="images/g.gif" />
<mapID target="addfav_icon" url="images/addfav_icon.gif" />
...
</map>
|
Returning to the original HelpSet, you can see that the next file type is navigation files. The four kinds of navigation files are TOC, Index, Glossary, and Favorites. The help system reads the information in these files to build the four types of navigation views and then displays them in the navigation pane. I'll go over the properties of each navigation file in detail.
TOC
Each <tocitem> element can have the
attributes text, target, and image, as
shown in Listing 7. The value of the text
attribute is the text label of a tocItem. The
value of the target attribute is a map ID
representing a help topic file. The image
attribute specifies a picture displayed to the left of a tocItem. If you do not specify an image, the help
system will employ a default one, as shown in the fourth part of Figure 2. Listing 7 shows part of the TOC file for the
Tax Calculator help system.
Listing 7. TaxCalculatorTOC.xml
<toc version="2.0">
...
<tocitem text="Pages" image="topLevel">
<tocitem text="About Page" target="about" image="secondLevel" />
<tocitem text="Color Chooser" target="colorChooser" />
</tocitem>
...
</toc>
|
Index
Each <indexitem> element can have the
attributes text and target. The value of the text attribute is the text label of an indexItem. The value of the target attribute is a map ID representing a help
topic file. Listing 8 shows part of the index file for the Tax
Calculator help system.
Listing 8. TaxCalculatorIndex.xml
<index version="2.0">
...
<indexitem text="Color">
<indexitem text="Changing Color" target="changeColor"/>
<indexitem text="Color Chooser" target="colorChooser"/>
</indexitem>
...
</index>
|
Glossary
Glossary files also use the <indexitem>
element, as shown in Listing 9.
Listing 9. TaxCalculatorGlossary.xml
<index version="2.0">
...
<indexitem text="Button" target="button_def"/>
...
</index>
|
Favorites
The help system generates the Favorites.xml
file automatically. It is stored in usrdir/javahelp. When
more than one JavaHelp system is installed in the same machine, only the
Favorites.xml of the latest running help
system will be kept.
Topic files are in HTML format. It is advisable to specify
the <title> tags in the HTML files,
because the <title> tags will be used in
the search database for the full text search -- you'll learn about that shortly.
After you've coded the topic files, navigation files, the map file and the helpset file, you can open up the helpset by running hsviewer.jar in %JAVAHELP_HOME%\demos\bin. Figure 3 shows what happens when you browse TaxCalculatorHelpSet.hs and click Display.
Figure 3. The Tax Calculator HelpSet in the hsviewer

Invoking JavaHelp from a Java application
After you've built a basic help system, you'll want to be able to
invoke it from your Java application. The JavaHelp system can be invoked
via a click on a button or a menu item. Listing 10 shows two approaches
to invoking the help system using a button. For either approach, the
first step is to create a new helpset (as you've done in the previous
exercises) and create a help broker for it. You can then use the
help broker's enableHelpOnButton() method to
call a help system from a button or, alternatively, you could simply add
an action listener called CSH.DisplayHelpFromSource(). When the button is
clicked, the action listener will get the helpID for the action source and display the helpID in the help viewer. Both approaches are
shown in Listing 10.
Listing 10. ButtonHelp.java
...
help_but=new JButton("Help");
...
Classloader loader = ButtonHelp.class.getClassLoader();
URL url = HelpSet.findHelpSet(loader, "TaxCalculatorHelpSet");
try {
hs = new HelpSet(loader, url);
} catch (HelpSetException e) {
...
}
HelpBroker helpbroker = hs.createHelpBroker("Main_Window");
/**-----the first way of calling a help system------------
helpbroker.enableHelpOnButton(help_but, "overview", hs);
/**-----the second way of calling a help system-----------
ActionListener contentListener = new CSH.DisplayHelpFromSource(helpbroker);
CSH.setHelpIDString(help_but, "overview");
help_but.addActionListener(contentListener);
*/
|
Invoking the help system from a menu item is a similar procedure. See ButtonHelp.java in the article source code (in Resources) to learn more about invocation with a button, and MenuItemHelp.java to learn about invocation with a menu item.
Although the default JavaHelp help system is good for starting out, you likely will want to customize its look and feel to better fit with your application. In this section, you'll learn how to configure special icons for GUI components, customize the navigation tabs and toolbar, and set the help system fonts.
The JavaHelp title bar icon, toolbar button icons, and navigation
tab icons are configurable in the helpset file. The title bar icon is
set using the <presentation> tag; a
toolbar button icon can be set as an attribute of the <helpaction> element of the <presentation> tag; and a navigation tab
icon can be set in the <view> tag.
Additionally, the navigation file item icons can be set in the
navigation file.
You can use the default image tabs for your help system or use
textual ones. To use textual tabs, set the displayviewimages attribute of the <presentation> tag to false in TaxCalculatorHelpSet.hs. For
example, the code <presentation default="true"
displayviewimages="false"> will result in the text-based tabs
shown in the second panel of Figure 4.
Figure 4. Image tab and textual tab

Note that the words displayed on the textual tabs shown in Figure 4 are the
values of the <label> elements of the
<view> tags in the helpset file
TaxCalculatorHelpSet.hs.
It's possible to display the help window without a toolbar. To
decide which option you like best, run ButtonHelp.class from the
ButtonHelp.java file and click the Help button. You'll see two
help windows, one with a toolbar and the other without it. If you prefer
no toolbar, simply create a <presentation> tag without the <toolbar> element in the helpset file
TaxCalculatorHelpSet.hs.
It's fairly easy to set the font for your help system. For example,
the code Font font = new Font("SansSerif", Font.ITALIC, 10); helpbroker.setFont(font); will result in the custom font display shown in Figure 5b as compared to the default shown in Figure 5b.
Figure 5a. Default font display

Figure 5b. Custom font display

Working with presentation windows
There are three types, or layers, of help window in a JavaHelp help system:
- The main window can be iconized, resized, moved by the user,
and closed by the user. The main window contains a toolbar, a
navigation pane, and a content viewer by default.
- The secondary window can be iconized, resized, moved by the
user, and closed either by the user or when the help viewer is closed.
It can contain a toolbar and a navigation pane, but by default it will
contain only a content viewer.
- The popup window is especially used for context-sensitive help, although it can be customized for multiple purposes. This window cannot be resized or moved and is closed when it is no longer in focus. It contains only a content viewer.
Moving information between the different presentation windows is
simple; you can do it by configuring the topic files or by calling
functions in Java code. Embedding a <a
href=url> tag in a given topic file will result in the linked
file being opened in the current window when called, although you will
need to do a little more if you want to display a new topic file in a
secondary window or popup window (discussed further below). For more
finely tuned presentation, you can use the methods with the argument
presentation in the JavaHelp API. For example, the enableHelpOnButton() of the HelpBroker class would appear as follows:
enableHelpOnButton(java.lang.Object obj, java.lang.String id, HelpSet hs, java.lang.String presentation, java.lang.String presentationName) |
If you go this route, you willneed to choose main window, secondary window, or popup window for the argument to presentation. For example, the following line would enable the user to
open the help topic in a secondary window by clicking the button help_but:
helpbroker.enableHelpOnButton(help_but, "overview", hs, "javax.help.SecondaryWindow", "main"); |
If you choose to work with topic files rather than calling functions in
Java code, then you will need to add the <object> tag
to the HTML files to move files between different types of windows.
Listing 11 shows how to open a secondary window using the
<object> tag.
Listing 11. Open a secondary window
<object CLASSID="java:com.sun.java.help.impl.JHSecondaryViewer">
<param name="id" value="about">
<param name="viewerActivator" value="javax.help.LinkLabel">
<param name="iconByName" value="../images/topLevel.gif">
<param name="viewerSize" value="350,400">
<param name="viewerName" value="TaxCal">
</object>
|
The <object> tag takes multiple parameters. Table 1 introduces the 15 valid parameters to the <object> tag for the secondary window (CLASSID="java:com.sun.java.help.impl.JHSecondaryViewer).
Table 1. Valid parameters to the object tag
| Function | Parameter | Remarks |
| Window | viewStyle | Can be set to javax.help.SecondaryWindow (the default) or java.help.Popup. |
| Content | id | Specifies content by map ID, which is defined in the map file. |
| Content | content | Specifies content by relative URL. |
| Activator | viewerActivator | Can be set to javax.help.LinkButton (the default) or javax.help.LinkLabel. |
| Size | viewerSize | Example: value="300, 400" indicates the window is 300 pixels wide and 400 pixels high. |
| Location | viewerLocation | Example: value="300, 400" indicates the window is located 300 pixels from the left and 400 pixels from the top. |
| Name | viewerName | Sets the name of window. Works only with secondaryWindow; Popup window ignores this parameter. |
| Icon | iconByID | Specifies the image by map ID which is defined in the map file. |
| Icon | iconByName | Specifies the image by relative URL. |
| Text | text | A string that will be seen by the user. |
| Text characteristics | textFontFamily | Can be set to Serif, SansSerif, Monospaced, Dialog, DialogInput, or Symbol. |
| Text characteristics | textFontSize | Can be set to xx-small, x-small, small, medium, large, x-large, xx-large, bigger, smaller (the unit for bigger and smaller is 1), nnpt (sets the font size to a specific point value of nn), +n ,-n (+n and -n is to increase and decrease the current base font size by a value of n), n (sets the font size to the point size associated with the index n). |
| Text characteristics | textFontWeight | Can be set to plain or bold. |
| Text characteristics | textFontStyle | Can be set to plain or italic. |
| Text characteristics | textColor | Can be set to black, blue, cyan, darkGray, gray, green, lightGray, magenta, orange, pink, red, white, or yellow. |
An activator is an object the user clicks to activate a
presentation window (popup or secondary). Using the parameter
viewerActivator and the parameter
text or
icon will generate four kinds of activators: Text Label,
Image Label, Text Button, or Image Button, as shown in Figure 6.
(Note that the second activator is the result of the code
in Listing 11.)
Figure 6. The four kinds of activator

As one of the results of clicking the second or the fourth activator
on the About page shown in Figure 6, you would find the invoked
secondary window almost the same as the main window. If you refer back
to the <presentation> tag of the
helpset file, you'll see that you set the Main_Window presentation to default. Because the secondary window also uses this
default presentation, it also has a navigation pane and toolbar.
See about.htm for the complete code and demonstrations of the invocation of presentation windows.
Context-sensitive help is an especially user-friendly way to deliver information to your users. When a user clicks a particular icon or field -- such as the Calculation fields shown in the examples below -- a pop-up window explains the function or next step that goes with that field. Context-sensitive help can be classified in one of three categories:
- Window-level help: When the Java application's window has
the focus, the user presses the Help key (F1) to launch the help system
with a specific topic, which usually is an introductory topic.
- Field-level help: When a specific component on the Java
application's GUI, such as a text field or button, has the focus, the
user presses the Help key (F1) or clicks a button to launch the help
system with a specific topic describing the current component.
- Screen-level help: The user clicks a button to invoke the help system with a specific topic that describes the current screen of the application.
I'll go over the basics of invoking each type of context-sensitive help in the sections that follow. See the file ContextSensitiveHelp.java for the complete source to go with the code examples.
Window-level help is invoked when a user is in a given application window and decides that he or she needs help. The user can invoke window-level help by pressing the Help key (F1). The invoked help system is shown in Figure 7.
Figure 7. Window-level help invoked with the Help key (F1)

In order to enable the Help key (F1) for the Tax Calculator window
shown in Figure 7, you would call helpbroker.enableHelpKey(getRootPane(), "personal",
hs);. Notice that I have set the help topic with map ID personal for the help system. Note that helpbroker.enableHelpKey() works only with the
rootPane of a JFrame in a Swing-based
application or a java.awt.Window in an
AWT-based application. I will discuss how you can enable the Help key
for field level components shortly.
Field-level help is launched from focus, meaning the location of the
cursor, and a press of the Help key. Listing 12 shows how to use
CSH.DisplayHelpFromFocus() to enable the Help key
for field-level help.
Listing 12. Field-level help invoked with the Help key
CSH.setHelpIDString(maid_tf, "maid"); CSH.setHelpIDString(course_tf, "course"); CSH.setHelpIDString(income_tf, "income"); CSH.setHelpIDString(result_tf, "result"); ActionListener listener = new CSH.DisplayHelpFromFocus(hs, "javax.help.MainWindow", null); maid_tf.addActionListener(listener); course_tf.addActionListener(listener); income_tf.addActionListener(listener); result_tf.addActionListener(listener); |
So, continuing the example from above, you click the Calculation tab
to switch to the calculation page and move the cursor to the first text
field on the page, which is called maid_tf.
When the cursor is flashing inside maid_tf, press F1 to display the Maid Levy help topic in the main window, as shown in Figure 8.
Figure 8. Field-level help invoked with the Help key

It is also possible to set up field-level help to be invoked from a
button such as the one with an arrow shown in Figure 9. For this,
you would use CSH.DisplayHelpAfterTracking(), as
shown below:
help_but.addActionListener(new CSH.DisplayHelpAfterTracking(hs,"javax.help.Popup", "popup")); |
Notice the additional pop-up window to present the help
topics. When you click the arrow button and move the cursor to the
maid_tf field, and then click the mouse, a
popup window with help topic Maid Levy will be displayed, as shown in
Figure 9.
Figure 9. Field-level help invoked with a button

Screen-level help is invoked when a user in a given application screen requests information (or help) about that screen by clicking a button. In this example, I have a tabbed pane with four different screens. Listing 13 shows one way to display help according to the current screen.
Listing 13. Screen-level help
menu.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent evt) {
int sel = menu.getSelectedIndex();
if(sel==0) CSH.setHelpIDString(help_but1, "about");
else if(sel==1) CSH.setHelpIDString(help_but1, "preference");
else if(sel==2) CSH.setHelpIDString(help_but1, "personal");
else if(sel==3) CSH.setHelpIDString(help_but1, "calculation");
}
});
...
help_but1.addActionListener(new CSH.DisplayHelpFromSource(hs,
"javax.help.SecondaryWindow", "secondary"));
|
The object help_but1 represents the button
with the word Help in Figure 10. I add a ChangeListener for the tabbed pane menu. Whenever the focus is changed to a new
screen, use CSH.setHelpIDString() to set a
new helpID for the help_but1.
Notice that there is an additional action listener called CSH.DisplayHelpFromSource() for the help_but1. When the user clicks the button, the action
listener will get the current helpID for the action source
(that is, help_but1) and display the
helpID in the help viewer. Therefore, regardless of how the
user switches screens (using tabs or menu items), the help system will
display correct information for the current screen.
Figure 10 shows that when the user switches to the Preference screen the specific topic describing preferences is displayed.
Figure 10. Screen-level help

After you have built a default online help system, it is possible to
embed it directly into your application's interface. Listing 14 shows
how to embed a TOC view into the example Tax Calculator application.
toc is a JPanel, and the tabbedpane will associate the toc JPanel to the tab TOC. The argument for
getNavigatorView() must be the same as the
view's name defined in the helpset file. It is case sensitive. You can embed other navigation views into the application in a similar
way.
Listing 14. EmbeddedHelp.java
viewer = new JHelpContentViewer(hs);
viewer.setPreferredSize(new Dimension(250,220));
navTOC = (JHelpTOCNavigator)hs.getNavigatorView("TOC").createNavigator(viewer.getModel());
navTOC.setPreferredSize(new Dimension(150,220));
toc.add(navTOC);
toc.add(viewer);
|
Figure 11 shows the results of embedding the TOC into the Tax Calculator application. Note that the help system will be displayed only when the menu item Show is checked.
Figure 11. Embedded help

Search functionality is an essential part of your help system. In order to utilize this functionality, you will need to create a search database. The JavaHelp API includes a feature to automatically index your help topics directory and build the search database for you. Follow these steps to create the search database:
- Set the directory where your help topics reside as the current
directory. src\TaxCalculator is the directory for the example.
- Run the
%JAVAHELP_HOME%\javahelp\bin\jhindexerTaxCalculatorcommand. Remember that src\TaxCalculator is the directory where the topic files are stored. This will create an indexed folder named JavaHelpSearch in the current directory. - Run the
%JAVAHELP_HOME%\javahelp\bin\jhsearchJavaHelpSearchcommand to verify the validity of the search database. If you see the messageinitialized; enterquery, then the search database has been successfully created.
Stop words are common words that will deliver no result when searched. Below are the default stop words used when creating the search database.
| a | all | am | an | and | any | are | as | at | be |
| but | by | can | could | for | from | etc | does | do | did |
| goes | got | had | has | have | he | her | him | his | how |
| if | in | is | it | let | me | more | much | must | my |
| nor | not | now | of | off | on | or | our | own | see |
| set | shall | she | should | so | some | than | that | the | them |
| then | there | these | this | those | though | to | too | us | was |
| way | we | what | when | where | which | who | why | will | would |
| yes | yet | you |
Figure 12 shows what happens if you search for the word how
in the search view of EmbeddedHelp. No result is
displayed because how is a stop word by default.
Figure 12. Search results with default stop words

Customizing the stop words list
It is possible to create a custom list of stop words. For example,
let's say that you wanted to exclude the word how from the default
list of stop words. There are two ways to do this, both requiring the
use of a configuration file. For the first method, you would create a
configuration file (config.txt) and then store the stop words in
a different file named stopWords.txt. The file config.txt
would then specify the location of the stop words file using the line
StopWordsFile stopWords.txt.
Listing 15 shows the custom stop words file, in which the word how is excluded. Note that every stop word must start with a new line in stopWords.txt.
Listing 15. stopWords.txt
a all ... his if ... |
You can also contain all of your stop words directly in the configuration file. For this, you simply create a configuration file named config1.txt and add the stop words directly in the configuration file, as shown here:
StopWords a, all,..., his, if... |
To index with the custom list of stop words you would make src
your current directory and run the command %JAVAHELP_HOME%\javahelp\bin\jhindexer -c config.txt
TaxCalculator. Replace config.txt in the command with your own configuration file. For example, if you run the jhindexer command with -c config1.txt and
then re-run the search for the word how in the EmbeddedHelp view, it will return several result
entries, as shown in Figure 13.
Figure 13. Search results with custom stop words

The red circle in the search window indicates the relevance of the
result entry to the query. The more filled in the circle is, the more
relevant the result entry is. There are five levels of relevance. In
Figure 13, the number indicates the number of times the query has been
matched in the result file. The text to the right of the number is
extracted from the <title> tag of the
help system's topic files.
Large, modularized applications may require the creation of numerous helpsets, perhaps even by different teams working on various aspects of the application. It can be helpful to the user to view each helpset separately, but he or she may also want to see the entire helpset (or topic list) as one. To enable this, it is possible to merge helpsets.
There are four merge types in JavaHelp 2.0: SortMerge, UniteAppendMerge, AppendMerge, and NoMerge. The four merge types and their features
are listed in Table 2.
Table 2. JavaHelp 2.0 merge types
| SortMerge | UniteAppendMerge | AppendMerge | NoMerge |
| This merge type sort entries alphabetically. If an entry in a new view has the same text and target as an entry in the existing view, the two entries will become one entry in the merged view. If only the texts are the same, the helpset title will be added at the end of the entry. | This merge type remains the hierarchy of the existing view. It merges matching elements of the two views into one element, and then merges and sorts any subelements of the matching elements. It appends any remaining elements to the end of the existing view. | This merge type simply appends the new view data after the existing view data. | No merging is performed. |
| Default merge type for the Search view. | No view uses this merge type by default. | Default merge type for the TOC, Index, and Glossary views. | Default merge type for the Favorites view. |
Each merge type is specified in the helpset file or in the navigation files. In order to properly merge, the name of views of the existing helpset and the new helpsets must be the same. You can merge helpsets statically or dynamically.
You can merge helpsets statically by adding the <subhelpset> tag in the existing helpset
file. If you use the absolute path, the location should have the prefix
file:\, as in: <subhelpset
location="file:\...\helpset.hs">. If you use the relative
path, the location should look something like this: <subhelpset location="helpset.hs">.
You can merge helpsets dynamically using the methods hs.add(hs1); hs.remove(hs1). hs is the existing helpset and hs1 is the new helpset. To see the results of a
dynamic merging operation, see MergeHelp.java in the article
source and run MergeHelp.
In Figure 14 there are two helpset TOCs and then the results of merging them.
Figure 14. Merge




The merged helpset in the third panel of Figure 14 is the result of adding the
attribute mergetype="javax.help.UniteAppendMerge" to the
existing helpset's TOC view tag, as shown in Listing 16.
Listing 16. Mergetype attribute -- TaxCalculatorHelpSet.hs
<view mergetype="javax.help.UniteAppendMerge"> <name>TOC</name> <label>TOC</label> <type>javax.help.TOCView</type> <data>TaxCalculatorTOC.xml</data> </view> |
The fourth panel of Figure 14 shows the result of adding the
attribute mergetype="javax.help.SortMerge" to
the tocitem Pages in the TOC navigation file
of the existing helpset, as shown in Listing 17. Note the different
presentation of the Pages topic in the third and fourth panels. In the
third panel, the elements of the new view are appended at the end of the
existing view. In the fourth panel, the elements of the new view and the
existing view are sorted alphabetically.
Listing 17. Mergetype attribute -- TaxCalculatorTOC.xml
<tocitem text="Pages" image="topLevel" mergetype="javax.help.SortMerge">
...
</tocitem>
|
When the menu item Add is checked, the two helpsets are merged. When the menu item is unchecked the application removes the second helpset from the first.
The Java platform's lightweight component class has many
applications in customizing your help system. For example, you've
already seen how to use the lightweight component class JHSecondaryViewer and the <object> tag to create and open secondary
and popup windows. In this section, you'll build on that exercise to
create your own lightweight component and then manipulate it using the
<object> tag. You'll develop a
component class, LightWeightCom, that plays
an audio clip when the user clicks an image.
See the article source, LightWeightCom.java and LightWeightComBeanInfo.java, to follow along with the examples in this section. To see the results, go to about.htm.
The BeanInfo class shown in Listing 18
provides explicit information about the lightweight component. It must
extend SimpleBeanInfo. getPropertyDescriptors() is the only method used by
ContentViewer in this class.
Listing 18. LightWeightComBeanInfo.java
public PropertyDescriptor[] getPropertyDescriptors() {
PropertyDescriptor back[] = new PropertyDescriptor[4];
try {
back[0] = new PropertyDescriptor("iconByName", LightWeightCom.class);
back[1] = new PropertyDescriptor("iconByID", LightWeightCom.class);
back[2] = new PropertyDescriptor("audioByName", LightWeightCom.class);
back[3] = new PropertyDescriptor("audioByID", LightWeightCom.class);
return back;
} catch (Exception ex) {
return null;
}
}
|
The lightweight component class must directly extend java.awt.Component or java.awt.Container, or a class that implements a
lightweight component. The example extends JLabel, which is a class implementing a lightweight
component. If your component will make use of the information from View, then you must implement the setViewData() method of the com.sun.java.help.impl.ViewAwareComponent
interface. For the example audio component I will make use of View's helpset and document base information, as
shown in Listing 19.
Listing 19. LightWeightCom.java -- implement setViewData
public class LightWeightCom extends JLabel implements ViewAwareComponent {
...
public void setViewData(View v) {
myView = v;
doc = (HTMLDocument) myView.getDocument();
base = doc.getBase();
// Loop through and find the JHelpContentViewer
Component c = container = (Component) myView.getContainer();
while (c != null) {
if (c instanceof JHelpContentViewer) {
break;
}
c = c.getParent();
}
// Get the helpset if there was JHelpContentViewer
if (c !=null) {
TextHelpModel thm = ((JHelpContentViewer)c).getModel();
if (thm != null) {
hs = thm.getHelpSet();
}
}
}
...
}
|
The lightweight component should be able to accept parameters. For
example, Listing 20 is designed to accept the param
audioByID. The setAudioByID method
uses the helpset information retrieved from setViewData(). The method gets the topic file
location using map ID, as shown below.
Listing 20. LightWeightCom.java -- setAudioByID
public void setAudioByID(String name) {
sound = null;
URL url=null;
Map map = hs.getCombinedMap();
try {
url = map.getURLFromID(ID.create(name, hs));
} catch (java.net.MalformedURLException e2) {
return;
}
sound = Applet.newAudioClip(url);
}
|
After compiling LightWeightCom.java and LightWeightComBeanInfo.java, add their classes to your classpath
and add the lines in Listing 21 to your help topic files. In this
example, I add them to about.htm. As a result, when the image
labels are clicked, different audio clips will be played. Note that
attribute CLASSID of the <object> tag must start with java:; otherwise, the help viewer will ignore it.
Listing 21. Object tag in about.htm
<OBJECT CLASSID="java:LightWeightCom">
<param name="iconByID" value="top">
<param name="audioByID" value="music">
</OBJECT>
<OBJECT CLASSID="java:LightWeightCom">
<param name="iconByName" value="../images/leaf2.gif">
<param name="audioByName" value="../audio/voice.au">
</OBJECT>
|
Server-based applications also need online help. In this section, you will learn how to present your help system to users on a network. In order to follow the exercises in this section, it will be helpful if you're familiar with the Tomcat Web server, as well as the basics of JavaBeans and JavaServer Pages (JSP) technologies, along with JavaScript and HTML scripts.
I'll use the Tomcat Web server 4.1.18 for the examples in this section. If you do not have Tomcat version 4.0 or higher installed on your development machine, you should install it now. (See Resources for more information.)
For the purpose of the exercises, create a folder in the webapps directory on the Tomcat Web server and name the folder TaxCalculatorHelp. For the simplest possible server-based help setup, I'll reuse the code from JavaHelp 2.0's serverhelp demo. You'll find this code in the %JAVAHELP_HOME%/demos/serverhelp/web directory. Copy all the .js, .html, .jsp, and .tld files and the subfolder images to your new TaxCalculatorHelp folder. Copy your own helpset files to this folder, too. Finally, in TaxCalculatorHelp, create a folder called WEB-INF and two subfolders called classes and lib, respectively. Copy jh.jar to WEB-INF/lib, and you should be set. See the article source for an example of this setup.
ServletHelpBroker is the JavaBeans component that stores
help state information, such as the helpset in use, the current ID, the
current navigation view, and other pieces of help information. Line 1 of
Listing 22 defines the help broker. Lines 2 and 3 set up the help broker
for a specific helpset by providing the helpSetName. Lines
4 to 6 merge a new helpset to the existing HelpSet. If the merge attribute is set to false, the
help broker will only work for the existing HelpSet.
Listing 22. JavaHelp server bean
1. <jsp:useBean id="helpBroker" class="javax.help.ServletHelpBroker" scope="session" /> 2. <jh:validate helpBroker="<%= helpBroker %>" 3. helpSetName="TaxCalculatorHelp/TaxCalculatorHelpSet.hs"/> 4. <jh:validate merge="<%= true %>" 5. helpSetName="TaxCalculatorHelp/ContextSensitive/HelpSet.hs" 6. helpBroker="<%= helpBroker %>" /> |
There are several important JavaScript files. tree.js is used to build a tree. The navigation trees for the TOC and Index views can be created using this file. You can use the code in Listing 23 to build a tree. The file searchList.js can be used to build a tree for the Search view. util.js checks whether any change in the content has occurred. If a change has occurred, an update will be fired with the change.
Listing 23. Build a tree
indexTree = new Tree(name, lineHeight, selectColor, showIcon, expandAll) indexTree.addTreeNode(parent, idnum, icon, content, helpID, URLData, expandType) indexTree.drawTree(); indexTree.refreshTree(); |
There are several important JSP files to review. navigator.jsp is used to get the views from the helpset file. javax.help.TOCView.jsp, javax.help.SearchView.jsp, and javax.help.IndexView.jsp each build their corresponding views. The help.jsp file controls the overall presentation of the help window. The top frame of the help window in Figure 15 shows banner. You may create your own banner by modifying the banner.html file. You can also exclude the banner. The lower-left frame of Figure 15 contains the file navigator.jsp and a tree navigator. The lower-right frame contains the file toolbar.html and the help topic content viewer. You can change the GUI presentation by moving the frame to another location and by including and/or excluding frames.
Let's look at the navigator.jsp file first.
Listing 24. navigator.jsp
<jh:navigators helpBroker="<%= helpBroker %>" >
<td classtableDefStyle BGCOLOR="<%= isCurrentNav.booleanValue()
? "white" : "#E5E5E5" %>" ALIGN="center">
<A class=tabbedAnchorStyle
HREF="navigator.jsp?nav=<%= name %>">
<IMG src="<%= iconURL!=""? iconURL : "images/" +
className +".gif" %>" Alt="<%= tip %>" border=0>
</A>
</td>
</jh:navigators>
|
Table 3 lists all the JSP extensions. Note that all JSP extensions must
start with the notation jh:.
Table 3. JSP extensions
| Tag | Description | Attribute |
validate | Sets up a help broker with a new helpset, which can be merged with another helpset. It can also specify the current ID | Required attribute: helpbroker; non-required attributes: setInvalidURL, helpSetName, currentID, merge |
navigators | Returns navigatorView information for the given help broker | Required attribute: helpbroker; non-required attribute: currentNav |
tocItem | Returns tocItem information for the given TOCView | Required attributes: tocView, helpbroker; non-required attribute: baseID |
indexItem | Returns IndexItem information for the given IndexView | Required attributes: indexView, helpbroker; non-required attribute: baseID |
searchTOCItem | Returns SearchTOCItem information for the given SearchView | Required attributes: searchView, helpbroker; non-required attribute: baseID |
Note that the scripting variables are nested within the body of the
JSP extensions navigators, tocItem, indexItem, and
searchTOCItem. Therefore, Listing 24 gets all
views from the helpset file using the nested variable name. The
table below shows the variables you can use between the
<jh:navigators> beginning tag and ending tag.
Table 4. Navigator variables
| Variable | Data type | Description |
classname | String | Name of the NavigatorView class; for example, javax.help.TOCView |
name | String | Name of the view defined in the helpset; in the example, it's "TOC" for NavigatorView class javax.help.TOCView |
tip | String | Tooltip text for the view |
iconURL | String | Location of the icon defined in the image attribute of the view in the helpset |
Now, let's look at the file javax.help.TOCView.jsp.
Listing 25. javax.help.TOCView.jsp
tocTree = new Tree("tocTree", 16, "ccccff", true, false);
<% TOCView curNav = (TOCView)helpBroker.getCurrentNavigatorView(); %>
<jh:tocItem helpBroker="<%= helpBroker %>" tocView="<%= curNav %>" >
tocTree.addTreeNode("<%= parentID %>","<%= nodeID %>","<%= iconURL!=""?iconURL:"null" %>",
"<%= name %>","<%= helpID %>","<%= contentURL!=""?contentURL:"null" %>",
"<%= expansionType%>" );
</jh:tocItem>
tocTree.drawTree();
tocTree.refreshTree();
|
This code builds a TOC navigation tree for the current helpset. The
navigation trees for the Search and Index views can be created in a
similar way. You already know the JSP extensions tocItem,
indexItem, and searchTOCItem, and their
attributes. Next, you will learn their nested variables, which can be called
between the <jh:tocItem>,
<jh:indexItem>, and <jh:searchTOCItem>
beginning and ending tags, from the Tables 5 and 6 below.
Table 5. Features of the tocItem and indexItem variables
| Variable | Data type | Description |
name | String | Text set with the "name" attribute of tocItem or IndexItem |
target | String | Target set with the "target" attribute of tocItem or IndexItem |
parent | String | Hex value identifying the parent code |
parentID | String | String identifying the parent code |
node | String | Hex value identifying current node |
nodeID | String | String identifying current node |
iconURL | String | Location of the icon defined in the "image"
attribute in the tocItem or IndexItem |
contentURL | String | URL of the content represented by this item |
isCurrentNav | Boolean | True if current navigator, false
otherwise. Note: This variable is available only for tocItem |
Table 6. Features of the searchTOCItem variable
| Variable | Data type | Description |
name | String | Name of searchTOCItem |
helpID | String | ID associated with searchTOCItem |
confidence | String | Relevance level of the result to the query |
hits | String | The number of times the query has been matched in the result file |
contentURL | String | Location of the content |
hitBoundries | String | A list of boundaries |
The final step of any development process is, of course, to test the results of your work. To test the server-side help system, follow these steps:
- Run the Tomcat server
- Open your Web browser
- Go to the URL http://127.0.0.1:8080/TaxCalculatorHelp
Following the links on the Web page, you'll find the server-based help system. When following the first link, you will see a window the same as the one in Figure 15a. When you follow the second link, you will see a window the same as the one in Figure 15b.
Figure 15a. Server-based help

Figure 15b. Server-based help

This article has served as an introduction to JavaHelp 2.0, the Java platform's help system API. With JavaHelp, you can easily incorporate a full-featured, standard help system into any Java application, component, or device. A standalone JavaHelp help system can run on any platform and can be embedded into any application. With JavaHelp 2.0, it is also possible to develop a robust, although not so full-featured, help system for users on a network.
JavaHelp 2.0 has many great features, which we've begun to explore together in this article. Through step-by-step explanation and exercises, you have learned how to create and manipulate the topic files, navigation files and helpset data files at the core of the JavaHelp 2.0 help system. You have also learned how to customize your helpset, embed it into your existing Java application, merge helpsets, create lightweight component add-ons for your help system, offer your users context-sensitive help, and more. We concluded the article with an introduction to the server-side help features of the JavaHelp 2.0 API.
From here, I encourage you to practice what you've learned. Study the article source and try building different features and different types of help systems using the JavaHelp 2.0 API. See the article Resources for further reference.
| Name | Size | Download method |
|---|---|---|
| j-javahelp2-source.zip | 776 KB | HTTP |
Information about download methods
- See the Java technology home page to download the latest J2SE JDK.
- If you don't already have it, you'll need to install Tomcat 4.0 or higher to complete the exercises in this article.
- See Sun's JavaHelp home page to learn more about the JavaHelp 2.0 API.
- For further reference, see the JavaHelp 2.0 system user's guide.
- The article "Sun Officially Unveils JavaHelp 2.0 Beta" (WinWriters.com, 2003) offers additional insight on the pros and cons of JavaHelp 2.0.
- For a book-length introduction to the JavaHelp API, see Creating Effective JavaHelp by Kevin Lewis (O'Reilly, 2000).
- You'll find articles about every aspect of Java programming in the developerWorksJava technology zone.
- Browse for books on these and other technical topics.
- Also see the Java technology zone tutorials page for a complete listing of free Java-focused tutorials from developerWorks
.

Nancy Chen Junhua is a freelance software consultant and developer with many years of experience. She is also pursuing research on agent learning at Nanyang Technological University, Singapore. You can contact Nancy at nancy_chenjunhua@ yahoo.com.
Comments (Undergoing maintenance)





