Providing end-user documentation can be the difference between a polished application and a throwaway product. Communicating to non-technical end users raises the bar even higher. Now that your team has created documentation, how do you deliver it to your user base? Don't re-invent the wheel -- you can deliver professional online help with minimal work.
This tutorial introduces you to an existing toolchain that will format and present your user manual within your Java application. Open standards and open source code will be leveraged. We want to use a Java-based framework, and to keep things flexible, we will be writing and maintaining our documentation in XML. A stylesheet that is freely available will serve as the glue.
Empowered with these tools and this tutorial, you will be able to deliver an online help system with minimal effort and research time.
This is an intermediate- to advanced-level article and assumes that you have a basic understanding of XML, the ability to use a command line, knowledge of how to set environment variables and other installation techniques for your operating system, and of course, knowledge of the Java programming language. In this tutorial, we will be installing JavaHelp, Saxon, and DocBook-xsl. Links to these packages will be given as we go along, and all links are organized at the end of this article.
JavaHelp is an online help framework developed by Sun Microsystems and written in the Java programming language. It uses existing W3C standards: HTML 3.2 for content and markup, and XML for metadata. It also ships with a full-text search engine.
Currently, JavaHelp is an add-on product from Sun, so you will need to download it from their web site. We will use release version 2.0 for this article. There are a few things you'll need to do before using it in a Java program.
JAVAHELP_HOME, and set it to the directory where you unzipped.CLASSPATH.PATH environment variable.Here's what the last three steps look like in bash or similar shells:
export JAVAHELP_HOME=/usr/java/jh2.0
export CLASSPATH=$CLASSPATH:$JAVAHELP_HOME/javahelp/lib/jhall.jar
export PATH=$JAVAHELP_HOME/javahelp/bin
or, on Windows:
SET JAVAHELP_HOME=C:\java\jh2.0
SET CLASSPATH=%CLASSPATH%;%JAVAHELP_HOME%\javahelp\lib\jhall.jar
SET PATH=%PATH%;%JAVAHELP_HOME%\javahelp\bin
You have probably used online help systems many times, but let's refresh our memories and check out what JavaHelp has to offer. Sun has cleverly packaged their User's Guide into a JavaHelp "help set". Execute this UserGuide.jar as follows:
java -jar $JAVAHELP_HOME/demos/bin/UserGuide.jar
or, on Windows:
java -jar %JAVAHELP_HOME%\demos\bin\UserGuide.jar
The UserGuide application will appear in a new window, as shown in Figure 1.

Figure 1. JavaHelp User's Guide shown in JavaHelp browser
What we are now looking at is the typical two-paned window layout. By clicking the tabs on the left pane, we can look at the Table of Contents, Index, Favorites and Search views. The pane on the right displays the actual contents for the topic you have selected.
So we have an idea of what we want our online help to look like, but where do we start?
|
Related Reading
DocBook: The Definitive Guide |
We could author our help files directly in HTML, one page per topic. We would then have to create the following metadata files:
However, creating and maintaining all of those files is a lot of work and prone to human error. Wouldn't it be nice to have a more semantically valuable way to mark up our content and let a program process it into our target framework?
DocBook is a standard format defined in both XML and SGML for writing books, articles, and especially technical documentation. We will use the XML "book" subset of DocBook. Although the DocBook DTD is vast, you don't need to learn every element in order to mark up your documents. We will focus on a small subset that is sufficient for delivering our online help system. We will be using Version 4.1.2, as maintained by the OASIS group.
As an example, I have created a User's Manual for the FooMatic 5000. You can download the entire example.xml. Below we will examine important fragments to learn how to mark up your documentation.
First, we include the standard XML declaration and doctype declaration:
<?xml version="1.0" standalone="no"?>
<?!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/DocBook/xml/4.1.2/DocBookx.dtd">
<book>
Next, we open the document with a <book> element. Our entire manual will be a child of this book element. This example is a single file, but for large manuals, you can obviously break up the file using standard XML inclusion techniques.
The first child of the book element is the bookinfo element, which sets the title to "FooMatic 5000."
<bookinfo>
<title>FooMatic 5000</title>
</bookinfo>
This becomes the name of our helpset. Here you may also add copyright, authorship, and other information.
Next we add a chapter element. Chapters become top-level nodes in our JavaHelp set.
<chapter>
<title>Quick Start</title>
<para>You know you can't wait!
Let's get started.</para>
</chapter>
This makes "Quick Start" the first item in the list of our help set's contents view. We can also create chapters with a deeper structure:
<chapter>
<title>How Do I...</title>
<section>
<title>New File</title>
<section>
<title>New Foo</title>
<para>New Files can be created
by going to the
file menu...</para>
</section>
<section>
<title>New Bar</title>
</section>
</chapter>
In this chapter, we have nested section elements to further break up a chapter into logical pieces. In this case, we have grouped together different actions. Sections create nodes in our table of contents and allow the user to drill down into the subject matter they need.
Sections contain paragraphs, which look like this:
<para><indexterm>
<primary>Importing</primary> an
<secondary>alien</secondary>
file format from </indexterm>
our competitors file formats has never...
<!-- more content -->
Here we mark up an important term or phrase inside of indexterm and primary tags (there are also secondary and tertiary tags for providing more context). Later, we will see these elements automagically create an entry in our JavaHelp index view.
The link tag is used to refer to another DocBook element by ID:
<para>Now that we have finished
installing, let's learn about some <link
linkend="concepts">Concepts</link>
used in FooMatic 5000</para>
</chapter>
<chapter id="concepts">
<title>Concepts</title>
...<!-- more content -->
</book>
In our chapter tag, we have set the attribute id to "concepts", which creates a target for the earlier link. When transformed by the JavaHelp stylesheets, these links will become anchor tags in HTML. Lastly, notice that we have finished our document with a closing book tag.
With just these few simple tags -- book, bookinfo, title, chapter, para, section, indexterm, primary, and link -- we have all of the tools we need for a simple help system. Other useful tags are tip, ulink, and screenshot.
Groovy, but how do we massage our DocBook file into JavaHelp? Somehow we need to metamorphose our single document into all of the files that make up the JavaHelp set.
|
DocBook XSL StyleSheets are a collection of stylesheets that allow you to transform your XML into PDF, HTML, and more importantly, JavaHelp format. This ability to derive JavaHelp and PDF from the same source is an extra bonus to us! With this approach, there is little added maintenance for delivering help in several formats to your users. This DocBook-xsl package is actually a set of stylesheets, so we also need an XSLT style engine to drive the transformations. We will be using the open source tool Saxon.
To get these tools:
CLASSPATH environment variable.For convenience you may set an environment variable, DOCBOOK_XSL_HOME, for DocBook, and you need to put saxon.jar in your CLASSPATH:
export DOCBOOK_XSL_HOME=/usr/local/DocBook-xsl-1.61.3
export CLASSPATH=$CLASSPATH:/usr/java/jar/saxon.jar
or, on Windows:
SET DOCBOOK_XSL_HOME=C:\local\DocBook-xsl-1.61.3
SET CLASSPATH=%CLASSPATH%;C:\java\jars\saxon.jar
Now that we have installed these libraries, we can use Saxon to generate our JavaHelp files from the DocBook markup (note that these commands should all be on one line):
java com.icl.saxon.StyleSheet example.xml
$DOCBOOK_XSL_HOME/javahelp/javahelp.xsl
or, on Windows:
java com.icl.saxon.StyleSheet example.xml
%DOCBOOK_XSL_HOME%\javahelp\javahelp.xsl
This will create the following output:
Writing ch01.html for chapter
Writing ch02.html for chapter
Writing ch03.html for chapter
Writing ch04.html for chapter(concepts)
Writing ch05s02.html for section
Writing ch05s03.html for section
Writing ch05s04.html for section
Writing ch05.html for chapter
Writing index.html for book
Writing jhelpset.hs
Writing jhelptoc.xml
Writing jhelpmap.jhm
Writing jhelpidx.xml
It seems a bit too easy, but we are really 90% complete. If we take a moment to think about the amount of time and effort we will save on creating and maintaining all of this HTML, we can see that it is worth the time of installing this toolchain. Examine the new files Saxon has created in a text editor. The files with the html extension are the contents of your help system, formatted in HTML 3.2 format. The reason for this older doctype is that JavaHelp displays these files with a JEditorPane, which can only handle 3.2 format. Swing's support for HTML is still maturing, but for most help systems, HTML 3.2 is adequate.
As for the other files, jhelpmap.jhm is a mapping file between JavaHelp's internal naming system, and the URLs and anchor names of your content. These system names are called "mapIDs". The jhelptoc.xml file describes our table-of-contents tree as it appears in the Contents view of our online help.
jhelpidx.xml is a list of index terms and their corresponding mapIDs. Lastly, jhelpset.hs is our entry point from the JavaHelp framework point of view. This file references our map, TOC, index, and which search engine implementation to use.
Did someone say search? If you look in the current directory, you will see many new files. We need to index our HTML pages for our search engine. From the current directory, execute:
jhindexer.sh .
This creates a new directory called JavaHelpSearch, which contains all of the data files that the default search engine requires.
If you can't wait to see what your help files look like, JavaHelp has another demo called hsviewer.jar. Invoke it from the command line (again, all on one line):
java -jar $JAVAHELP_HOME/demos/bin/hsviewer.jar
-helpset /path/to/current/directory/jhelpset.hs
or, on Windows:
java -jar %JAVAHELP_HOME%\demos\bin\hsviewer.jar
-helpset C:\path\doc\test\jhelpset.hs
This brings up your help set in the JavaHelp viewer, as seen in Figure 2.

Figure 2. Screenshot of example help set FooMatic 5000
Easy huh? Let's wire up JavaHelp to our application. In the next section, we will add a new ActionListener that shows our help set when the user clicks on a menu item.
In terms of integrating up our online help, the most important file that has been created is jhelpset.hs. If you open this file in a text editor, you will see that it is an XML file that tells JavaHelp where to find various pieces of our help set, including jhelpmap.jhm. This map file contains mapID elements and locations, which are your various HTML documents.
The JavaHelp API has three main classes that you will be using to leverage the framework: javax.help.HelpSet, javax.help.HelpBroker, and javax.help.CSH.DisplayHelpFromSource. The HelpSet represents our content and metadata that we generated from our DocBook. A HelpBroker is responsible for determining what to show, based on a HelpSet and a given mapID (which is basically an atomic piece of help). CSH.DisplayHelpFromSource is a convenience class that implements the java.awt.event.ActionEventListener interface and sets the system into motion upon callback.
//import help classes
import javax.help.*;
import javax.swing.*;
import java.net.URL;
String hsName = "myHelpSet.hs";
//Somewhere in your class
try {
ClassLoader cl =
OurClass.class.getClassLoader();
URL hsURL = HelpSet.findHelpSet(cl,
hsName);
hs = new HelpSet(null, hsURL);
} catch (Exception ee) {
System.out.println ("HelpSet "+
hsName + " not found");
return;
}
hb = hs.createHelpBroker();
JMenu help = new JMenu("Help");
menuBar.add(help);
menu_help = new JMenuItem("Contents");
menu_help.addActionListener(
new CSH.DisplayHelpFromSource(hb) );
In this example, JavaHelp searches the classpath for a HelpSet called myHelpSet.hs. If it is found, a HelpBroker is created. From that, we can create the CSH.DisplayHelpFromSource, which is an ActionListener that can be added to a JMenuItem, in this case the "Contents" menu item in the "Help" menu.
All of the files relating to your new help system should be distributed with your application.
If you .jar them up with your other resources, then a ClassLoader will be able to find and display the help set's pages, images, and data. JavaHelp is an add-on that your users may not have installed, so you will probably want to ship jh.jar and jsearch.jar with your application.
For further examples, open up the Java source files that ship with JavaHelp under the demos/src directory.
We have learned the basic techniques and API involved with integrating a JavaHelp system into your Java application. This is a brief tutorial, but JavaHelp, Saxon, and DocBook-xsl all have documentation under their respective directories. If DocBook has piqued your curiosity, Norman Walsh's DocBook: The Definitive Guide is an excellent reference. I encourage you to experiment with more DocBook tags, or customize the JavaHelp XSL stylesheets to your liking.
Austin King is a developer living and working in Seattle Washington, working with web applications, Open Source, and documentation tools.
Return to ONJava.com.
Copyright © 2009 O'Reilly Media, Inc.