Skip to main content

JavaHelp and Swing Application Framework

Posted by pkeegan on May 15, 2007 at 7:27 AM PDT

Updated 27 March 2008 to account for changes that appeared in NetBeans IDE 6.0 (and are still relevant for 6.1)

After a long long hiatus, I'm going to try my hand at blogging again. The main reason is to share things that I learn in my work in a more frequent and incremental way than I do with the tutorials I write. I expect this will also give me a nice chance to have more onversations with readers than you do when you are buried behind more monolothic documents. In doing this, I'm obviously taking a few cues from Geertjan.



At least initially, my focus will be on Swing things, old and new, particularly
as programmed in NetBeans. But whereas experienced programmers like
Hans and Josh are able to take on pretty sophisticated topics, I'll be taking an almost exclusively
"by dummies" angle.



To kick things off, I'll start with a topic I have a fairly long history with: in-product help (or "online help" as it's known in the industry, though I avoid this term because it is so obviously misleading to someone not familiar with industry jargon). The help
extension to the Java platform is called JavaHelp. It's now open source.



So how do you add help to a Swing application? I've written lots of help for NetBeans, but had never tried to program an application to use JavaHelp. But as I was playing around with recent development builds of NetBeans IDE 6.0, the Help menu that comes as part of the Java Desktop Application template all but dared me to try. As it turns out, it's pretty straightforward. The general procedure is:


  • Create basic metadata for a JavaHelp help set and a sample topic or two.
  • Add one of the JavaHelp binaries to your application's classpath.
  • Add code to connect the JavaHelp system to your application.




Let's do a run-through of this process using my favorite IDE, NetBeans. To spice things up a little, I'll use the NetBeans IDE 6.0 Preview (M9) release. This release is pretty far from final, but it's got a lot of cool things worth showing off, including support for the
Swing Application Framework. The most visible impact on this mini-tutorial will be the snazzy application skeleton you get without coding anything plus a simple way to handle actions. If you prefer to use the 5.5 version, the most essential points here will work. You just won't see the fancy new template or the Actions part of the Swing Application Framework in, ahem, action.



First we'll create a skeleton application that already has menus and windowing behavior built in.

  1. Choose File > New Project.
  2. Select the General category and then select the Java Desktop Application template.
  3. Click Next.
  4. On the Name and Location page of the wizard, type AppWithHelp for the project name.
    helpapp_newproj.png

  5. For application shell, select Basic Application.
  6. Click Finish.




To get the help set into your project directory:

  1. Download the basic help set that we will use (including metadata and help content).
  2. Unzip the file on your system.
  3. Copy the javahelp folder into the directory containing your project.
    (javahelp should be at the same level as code>src, test, and nbproject).




Now we have to make sure that the IDE knows to package the JavaHelp files in the application as part of the build process:

  1. In the IDE, right-click the AppWithHelp project and choose Properties.
  2. Select the Sources node.
  3. Next to the Source Package Folders table, click Add Folder.
  4. In the Add Source folder dialog box, select the javahelp folder and click Open.
    helpapp_addhelpfiles.png
  5. Click Close to exit the Project Properties dialog.
  6. In the Edit Project Properties dialog box that comes up, click Regenerate.

You can now view the help files from the Projects window and edit them in the Source Editor. When you build your project, the help files will be included in it. The metadata files are in the appwithhelp.docs package. A couple of dummy help topics are in appwithhelp.docs.content. For info on the metadata files and how JavaHelp works in general, check out the JavaHelp User's Guide.



Quick digression: Metadata for JavaHelp help sets are simple XML files. In the JavaHelp documentation, you
might notice that these files have special extensions (like .hs, .jhm, .idx, and .toc). However, we're using .xml as the
extensions for these files so that we don't have to do any extra configuring to get the IDE's XML editing features for them.



Now we need to add the basic JavaHelp library to the project and add the code that calls into that library.



To add the JavaHelp binary to the application:

  1. If you haven't already done so, download the JavaHelp distro from https://javahelp.dev.java.net/#binary
  2. Unpack the zip file.
  3. In the IDE's Projects window, right-click the
    AppWithHelp project's Libraries node and choose Add JAR/Folder.
  4. In the file chooser, navigate to the jh.jar file and click Open.
  5. You should find the jh.jar file in the javahelp2_0_04\jh2.0\javahelp\lib directory.




To add a method to the application that will open up your help set in the JavaHelp viewer:

  1. Open the appwithhelp/AppWithHelpFrame.java file.
  2. In the Source Editor, click the Source button to display the source view of the class.
  3. Insert the openHelp() method below directly into the class, perhaps in the area just above the taskMonitorPropertyChange method.
    Note the @Action annotation. You will see the use of this later in the tutorial.
    /**This method opens up the help viewer for specified help set 
    * and displays the home ID of that help set
    */ 
        @Action public void openHelp() {
        // Identify the location of the .hs file
        String pathToHS = "/appwithhelp/docs/appwithhelp-hs.xml";
        //Create a URL for the location of the help set
        try {
          URL hsURL = getClass().getResource(pathToHS);
            hs = new HelpSet(null, hsURL);
        } catch (Exception ee) {
            // Print info to the console if there is an exception
            System.out.println( "HelpSet " + ee.getMessage());
            System.out.println("Help Set "+ pathToHS +" not found");
            return;
        }
     
        // Create a HelpBroker object for manipulating the help set
        hb = hs.createHelpBroker();
        //Display help set
        hb.setDisplayed(true);
    }
  4. Add the following variable declarations as well, perhaps at the bottom of the file near the variables declaration guarded block.
        private HelpSet hs;
        private HelpBroker hb;
        private URL hsURL;
  5. Right-click in the Source Editor and choose Fix Imports.

    You should see the Fix All Imports dialog with recommendations for the HelpBroker, HelpSet, and URL classes.

  6. helpapp_fiximports.png

  7. Click OK to generate the import statments for the classes.
  8. Press Ctrl-S to save the file. The red error marks should then
    disappear (though it might take a few seconds).

Now we need a UI component for the user to open the Help from.
Let's create a menu item in the Help menu:

  1. In the Source Editor's toolbar, click the Design button to return
    the IDE to design mode for the AppWithHelpFrame.java file.
  2. In the Inspector window right-click JFrame > menuBar [JMenuBar] > helpMenu [JMenu] and choose Add From Palette > Swing Menus > Menu Item.
  3. Rename the variable from jMenuItem1 to contentsMenuItem.
    helpapp_inspector.png
  4. Right-click contentsMenuItem and choose Move Up.

You should now have a Help menu with two items (Item, About). You can test this in the form.



Finally, it's time to hook the menu item to the openHelp() method.

  1. In the Inspector window, select contentsMenuItem.
  2. In the Properties window, select the action property and select openHelp from the dropdown list. (Yes, the IDE detected that the openHelp method is an action
    because of the @Action annotation.)
    helpapp_action.png
  3. Back in the Inspector, right click contentsMenuItem and choose Set Action.
  4. In the Set Action dialog, set the following attributes:
    • Text: Contents...
    • Tool Tip: Opens the application's help window
    • Accelerator: control pressed H (entered by pressing Ctrl-H)

    helpapp_action-editor.png

  5. Click OK.

If you want to see what code was generated by these procedures,
click back to the AppWithHelpFrame.java file's Source View and
expand the Generated Code code fold. There you will find the
this snippet of code which adds the Contents menu item to the Help menu and connects it to the openHelp() method:

        
contentsMenuItem.setAction(actionMap.get("openHelp")); // NOI18N
contentsMenuItem.setText(resourceMap.getString("contentsMenuItem.text")); // NOI18N

contentsMenuItem.setName("contentsMenuItem"); // NOI18N
fileMenu.add(contentsMenuItem);




At this point, you should be able to see your application and JavaHelp in action:

  1. In the IDE, right-click the project node and choose Run Project. The project will build and, after several seconds, run.
  2. In the running application, choose Help > Contents, and see a Help window with a table of contents, index, and a few dummy topics.

helpapp_helpwindow.png



Here I've shown the most basic variant of adding a help set to your application. Another important aspect of this is setting up your application's build system to use JavaHelp. This will bring you the important benefits like the automatic creation of a search database
and validating help metadata. If I'm not distracted by something more pressing and there's enough demand, I'll might cover these topics in ensuing posts.

Related Topics >>

Comments

Hi I got the following error while I was incorporating the ...

Hi I got the following error while I was incorporating the help file in my java application......I couldn't figure out where the hs.xml file is. Please your help will be highly appreciated.

HelpSet Could not parse
Got an IOException (null)
Parsing failed for null
Help Set /appwithhelp/docs/appwithhelp-hs.xml not found