Using JavaHelp

Oracle's JavaHelp tool creates help systems for graphical applications, using HTML topic files and XML to define the topic hierarchy. Developers access its services through the javax.help package.

Here's an example of using javax.help to launch a JavaHelp system from a standard Help menu.

package hirondelle.stocks.help;

import java.awt.event.*;
import javax.swing.*;
import java.util.logging.*;
import javax.help.*;
import java.net.URL;
import hirondelle.stocks.util.Args;
import hirondelle.stocks.util.Util;

/**
* Display the help system for the application.
*
* <P>Display one of table of contents, index, or search tab, according 
* to argument passed to the constructor. This implementation uses 
* Sun's <a href=http://java.sun.com/products/javahelp/>JavaHelp</a> tool.
*
* <P>This action activates the Help key (often <tt>F1</tt>) for this application. 
* When the help key is pressed, the help system's table of contents is displayed.
*
* <P>This action is unusual in that it corresponds to more than one menu item 
* (Contents, Index, and Search).
*
* <P>Note: the displayed JavaHelp screen is not centered; it's left as is, 
* since the JavaHelp GUI is often cut off at the bottom anyway, and centering would 
* make this problem worse.
*/
public final class HelpAction extends AbstractAction {

  /**
  * Constructor.
  *  
  * @param aFrame parent window to which the help window is attached
  * @param aText name of the menu item for this help action
  * @param aMnemonicKeyEvent mnemonic for <tt>aText</tt>
  * @param aIcon possibly-null graphic to be displayed alongside the text, or 
  * in a toolbar
  * @param aView determines which help window is to be displayed: Contents, Index, 
  * or Search
  */
  public HelpAction(
    JFrame aFrame, String aText, int aMnemonicKeyEvent, Icon aIcon, View aView
  ) {
    super(aText, aIcon);
    Args.checkForNull(aFrame);
    Args.checkForNull(aText);
    Args.checkForNull(aView);
    fFrame = aFrame;
    fView = aView;
    putValue(SHORT_DESCRIPTION, "StocksMonitor Help");
    putValue(LONG_DESCRIPTION, "Displays JavaHelp for StocksMonitor.");
    putValue(MNEMONIC_KEY, new Integer(aMnemonicKeyEvent) );    
    initHelpSystem(); 
  }

  @Override public void actionPerformed(ActionEvent event) {
    fLogger.info("Showing help system.");
    fHelpBroker.setCurrentView( fView.toString() );
    fDisplayHelp.actionPerformed( event );
  }
  
  /** Enumeration for the style of presentation of the the Help system. */
  public enum View {
    SEARCH("Search"), 
    CONTENTS("TOC"), 
    INDEX("Index");
    @Override public String toString(){
      return fName;
    }
    private View(String aName){
      fName = aName;
    }
    private String fName;
  } 

  // PRIVATE 
  private JFrame fFrame;
  private View fView;
  /** Path used by a classloader to find the JavaHelp files. */
  private static final String PATH_TO_JAVA_HELP =
    "hirondelle/stocks/help/JavaHelp/HelpSet.hs"
  ;
  private ClassLoader DEFAULT_CLASS_LOADER = null;
  private static final Logger fLogger = Util.getLogger(HelpAction.class); 
  
  private HelpBroker fHelpBroker;
  private CSH.DisplayHelpFromSource fDisplayHelp;
  
  /** Initialize the JavaHelp system. */
  private void initHelpSystem(){
    //optimization to avoid repeated init
    if ( fHelpBroker != null && fDisplayHelp != null) return;
    
    //(uses the classloader mechanism)
    ClassLoader loader = this.getClass().getClassLoader();
    URL helpSetURL = HelpSet.findHelpSet(loader, PATH_TO_JAVA_HELP);
    assert helpSetURL != null : "Cannot find help system.";
    try {
      HelpSet helpSet = new HelpSet(DEFAULT_CLASS_LOADER, helpSetURL);
      fHelpBroker = helpSet.createHelpBroker();
      fHelpBroker.enableHelpKey( fFrame.getRootPane(), "overview", helpSet );
      fDisplayHelp = new CSH.DisplayHelpFromSource(fHelpBroker);
    }
    catch (HelpSetException ex) {
      fLogger.severe("Cannot create help system with: " + helpSetURL);
    }
    assert fHelpBroker != null : "HelpBroker is null.";
  }
}