Lend a helping hand to your Java applications

Build your next Java application help system with JavaHelp 2.0

Even help system designers can use a helping hand sometimes, and with JavaHelp 2.0, help is finally available. In this article, you'll learn how to use the Java platform's unique help system API to build a standard, full-featured, easy-to-use system for presenting online information to Java application users.

Share:

Nancy Junhua (nancy_chenjunhua@yahoo.com), Software Consultant and Developer

Nancy JunhuaNancy 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.



29 April 2004

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.

Getting started

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
A first look at the Tax Calculator application

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
Navigation icons

Installing JavaHelp 2.0

You'll find the JavaHelp 2.0 binary distribution on the JavaHelp home page. You must have the J2SE SDK with JDK 1.2.2 or higher installed on your development machine before you attempt to install the JavaHelp software. You can install the JavaHelp software by extracting the downloaded zip file to a directory of your choice. You should create an environment variable such as JAVAHELP_HOME to contain the path to the folder in which you installed JavaHelp 2.0. You should also put
%JAVAHELP_HOME%\javahelp\lib\jhall.jar
in your classpath.

Note that you must remove all prior releases of JavaHelp from your system before you install version 2.0.


Using the HelpSet

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.

The HelpSet data files

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.GlossaryView
  • javax.help.TOCView
  • javax.help.IndexView
  • javax.help.FavoritesView
  • javax.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:

  • BackAction
  • ForwardAction
  • SeparatorAction
  • HomeAction
  • ReloadAction
  • PrintAction
  • PrintSetupAction
  • FavoritesAction

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>

Navigation files

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

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
helpset viewer

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.


Customizing the look and feel

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.

Configuring icons

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.

Text or image-based tabs?

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
Image TabTextual 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.

Toolbar or no toolbar?

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.

Setting the font

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 5. Default font display
Figure 5b. Custom 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");

The <object> tag

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
FunctionParameterRemarks
WindowviewStyleCan be set to javax.help.SecondaryWindow (the default) or java.help.Popup.
ContentidSpecifies content by map ID, which is defined in the map file.
ContentcontentSpecifies content by relative URL.
ActivatorviewerActivatorCan be set to javax.help.LinkButton (the default) or javax.help.LinkLabel.
SizeviewerSizeExample: value="300, 400" indicates the window is 300 pixels wide and 400 pixels high.
LocationviewerLocationExample: value="300, 400" indicates the window is located 300 pixels from the left and 400 pixels from the top.
NameviewerNameSets the name of window. Works only with secondaryWindow; Popup window ignores this parameter.
IconiconByIDSpecifies the image by map ID which is defined in the map file.
IconiconByNameSpecifies the image by relative URL.
TexttextA string that will be seen by the user.
Text characteristicstextFontFamilyCan be set to Serif, SansSerif, Monospaced, Dialog, DialogInput, or Symbol.
Text characteristicstextFontSizeCan 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 characteristicstextFontWeightCan be set to plain or bold.
Text characteristicstextFontStyleCan be set to plain or italic.
Text characteristicstextColorCan be set to black, blue, cyan, darkGray, gray, green, lightGray, magenta, orange, pink, red, white, or yellow.

The four kinds of activators

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
activators

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.


Adding context-sensitive help

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

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)
Window-level help invoked with the Help key

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

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
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
Feld level help invoked with a button

Screen-level help

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
Context sensitive help--screen level help

Adding embedded 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
Embedded Help

Adding search functionality

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\jhindexerTaxCalculator command. 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\jhsearchJavaHelpSearch command to verify the validity of the search database. If you see the message initialized; enterquery, then the search database has been successfully created.

Stop words

Stop words are common words that will deliver no result when searched. Below are the default stop words used when creating the search database.

aallamanandanyareasatbe
butbycancouldforfrometcdoesdodid
goesgothadhashaveheherhimhishow
ifinisitletmemoremuchmustmy
nornotnowofoffonorourownsee
setshallsheshouldsosomethanthatthethem
thentherethesethisthosethoughtotoouswas
waywewhatwhenwherewhichwhowhywillwould
yesyetyou

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
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
define our own 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.


Merging helpsets

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
SortMergeUniteAppendMergeAppendMergeNoMerge
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.

Static and dynamic merging

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.

The results

In Figure 14 there are two helpset TOCs and then the results of merging them.

Figure 14. Merge
merge-before1merge-before2merge-aftermerge-after1

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.


Adding lightweight components

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 help

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.

Less service on the server

Although it is very robust, JavaHelp 2.0's server-based help provides fewer features than client-based help. Server-based help includes only the TOC, Index, and Search views, and it does not include support for using and creating lightweight components. As a result, you cannot open topic files in popup or secondary windows or create custom lightweight components for your server-side help system.

Setting up

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.

The JavaHelp server bean

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 %>" />

JavaScript files

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();

JSP files

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
TagDescriptionAttribute
validateSets up a help broker with a new helpset, which can be merged with another helpset. It can also specify the current IDRequired attribute: helpbroker; non-required attributes: setInvalidURL, helpSetName, currentID, merge
navigatorsReturns navigatorView information for the given help broker Required attribute: helpbroker; non-required attribute: currentNav
tocItemReturns tocItem information for the given TOCViewRequired attributes: tocView, helpbroker; non-required attribute: baseID
indexItemReturns IndexItem information for the given IndexViewRequired attributes: indexView, helpbroker; non-required attribute: baseID
searchTOCItemReturns SearchTOCItem information for the given SearchViewRequired 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
VariableData typeDescription
classnameStringName of the NavigatorView class; for example, javax.help.TOCView
nameStringName of the view defined in the helpset; in the example, it's "TOC" for NavigatorView class javax.help.TOCView
tipStringTooltip text for the view
iconURLStringLocation 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
VariableData typeDescription
nameStringText set with the "name" attribute of tocItem or IndexItem
targetStringTarget set with the "target" attribute of tocItem or IndexItem
parentStringHex value identifying the parent code
parentIDStringString identifying the parent code
nodeStringHex value identifying current node
nodeIDStringString identifying current node
iconURLStringLocation of the icon defined in the "image" attribute in the tocItem or IndexItem
contentURLStringURL of the content represented by this item
isCurrentNavBooleanTrue if current navigator, false otherwise. Note: This variable is available only for tocItem
Table 6. Features of the searchTOCItem variable
VariableData typeDescription
nameStringName of searchTOCItem
helpIDStringID associated with searchTOCItem
confidenceStringRelevance level of the result to the query
hitsStringThe number of times the query has been matched in the result file
contentURLStringLocation of the content
hitBoundriesStringA list of boundaries

Testing server-side help

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

Conclusion

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.


Download

DescriptionNameSize
Code samplej-javahelp2-source.zip776 KB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Java technology on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=10937
ArticleTitle=Lend a helping hand to your Java applications
publish-date=04292004