Connecting Help in NetBeans: From Help Set Installation to Hooking up Context-Sensitive Help

This document is designed to help NetBeans module writers with installing help into the IDE and correctly setting up context-sensitive help for their modules. The document covers the following topics:

Introduction

The IDE's architecture enables you to:

In order to take advantage of these help features, a NetBeans module writer must be aware of different aspects of the NetBeans help system, specifically:

Adding Help to GUI components

There is an overview of adding help to various GUI NetBeans components in the JavaHelp Integration API. This section expands a bit on the information provided there.

Explorer Nodes

If your node extends AbstractNode or one of its subclasses, you should implement the getHelpCtx method to return a HelpCtx for the node. The HelpCtx includes the specific Help ID for the help topic for this node. If the node is selected in the explorer and the user hits the F1 key, then the help associated with this node will be displayed.

public class MyNode extends AbstractNode{
    public HelpCtx getHelpCtx() {
        return new HelpCtx("org.netbeans.modules.xml.tree.nodes.XMLDataNode");   
    }
    // other methods...
}

Wizards

Wizards are basically a series of Swing Components that are displayed via a WizardDescriptor.Iterator object. The object that the developer creates must implement the WizardDescriptor.Panel interface which includes a method that the developer implements to return the actual Swing Component that is to be displayed (usually a JPanel is returned). Additionally, the developer must implement the getHelp method and return a HelpCtx for this particular wizard step. By default, the Help button is displayed on the resulting JDialog and when the user selects this Help button, the getHelp method is called for the currently displayed WizardDescriptor.Panel object.

public class MyWizardPanel implements WizardDescriptor.Panel {
    private JPanel p;
    public Component getComponent() {
	if (p == null) {
	    p = new JPanel();
            p.setLayout(new BorderLayout());
            p.add(/* etc. */);
        }
	return p;
    }
    public HelpCtx getHelp() {
        return new HelpCtx("org.netbeans.modules.xml.core.wizard.DocumentPanel");  
    }
    // other methods...
}

Dialogs

There are two different ways in which you can set help on a NetBeans dialog. If you wish to display a dialog of some sort, you typically create the Swing components you wish to display and then create a DialogDescriptor object which is a NetBeans object that is used to describe the behavior or the dialog. To display help:

  1. Specify the help on the DialogDescriptor object - As a rule, setting the help ID on the DialogDescriptor is the preferred way to set a help ID for a dialog. There are a couple of ways to do this:
  2. Set the help ID string on the displayed Swing Component - You'll notice that the DialogDescriptor constructor takes an Object which is typically the Swing Component to display in the JDialog. If you set the help ID string property on the Swing component, then this help id will be used as the help id for the JDialog and the corresponding help will be displayed if the user selects the Help button.
    JPanel p = new JPanel();
    // ...add Swing components to p ...
    HelpCtx.setHelpIDString(p, "panel_help_id");   
    DialogDescriptor dd = new DialogDescriptor(p, "Dialog Title");
    

If you do not supply a HelpCtx object for the DialogDescriptor or set the help ID string for the displayed Swing Component, then no Help button will be displayed on the JDialog that is displayed for this DialogDescriptor.

Property Sheets

When creating a Property Sheet, the developer creates a Sheet.Set object. To populate the Sheet.Set the developer creates and adds a number of Node.Property objects. To display help for the Property Sheet, you must call the setValue method and set the helpID property:

Sheet sheet = Sheet.createDefault();
Sheet.Set ps = sheet.get(Sheet.PROPERTIES);
ps.setValue("helpID", "org.netbeans.modules.xml.tree.nodes.XMLDataNode.Properties");  

Tabbed Property Sheets

Property sheets can actually contain multiple tabs, each having their own help associated with them. The method described above to set the help id of a Property Sheet still applies, the only difference is the way in which the additional Property Sheet is created:

Sheet sheet = Sheet.createDefault();
Sheet.Set referenceTab = new Sheet.Set();
referenceTab.setValue("helpID", "org.netbeans.modules.xml.tree.nodes.XMLDataNode.ReferenceProperties");  
referenceTab.setName("referenceTab"); // NOI18N
sheet.put(referenceTab);

Individual Properties

You can also set an individual help ID for each property (Node.Property) in a property sheet. Presently Sun Java Studio and NetBeans help is not provided on a per-property basis - help on individual properties is provided in the form of a tooltip.

Custom Property Editors

Some Properties displayed on a Property Sheet require a custom editor. The user accesses the editor by selecting the "..." button on an entry for a specific Property when the user selects that Property. The developer of the custom editor provides a Swing Component (typically a JPanel) which is ultimately displayed in a JDialog. If Help is to be supplied on the resulting JDialog, then the help ID string of the supplied Swing Component must be set.

public MyPropertyEditor extends PropertyEditorSupport{
    public Component TreeNodeFilterCustomEditor() {
	JPanel p = new JPanel();
	// ...add Swing components to p...
	HelpCtx.setHelpIDString(p, "org.netbeans.modules.xml.tax.beans.editor.TreeNodeFilterCustomEditor");   
	return p;
    }
    // other methods...
}

Tabbed Custom Property Editors

Some Custom Property Editors display a number of tabs. Depending on the tab that is displayed, different Help may need to be displayed. In this case, you should set the help ID on the property editor's JTabbedPane. If you want the help ID to change when the user switches tabs, then you should listen for changes in the selected tab, and change the ID on the JTabbedPane each time.

For NetBeans 3.4 and earlier, you can set help IDs on tabs as shown in this example:

class MyTabPane extends JTabbedPane implements ChangeListener {
    private HelpCtx[] helps = new HelpCtx[3];
    public MyTabPane() {
        add(new Panel1());
        helps[0] = new HelpCtx("help_1");
        // etc.
        stateChanged(null);
        addChangeListener(this);
    }
    public void stateChanged(ChangeEvent ignore) {
        HelpCtx.setHelpIDString(this, helps[getSelectedIndex()]);
    }
}

In NetBeans releases later than 3.4, you can use the HelpCtx.Provider to simplify the process, as shown in the following example:

class MyTabPane extends JTabbedPane implements HelpCtx.Provider {
    private HelpCtx[] helps = new HelpCtx[3];
    public MyTabPane() {
        add(new Panel1());
        helps[0] = new HelpCtx("help_1");
	// etc.
    }
    public HelpCtx getHelpCtx() {
	return helps[getSelectedIndex()];
    }
}

Merge Hints for TOC and Index

In NetBeans IDE 3.6, the help system has been upgraded to use v. 2.0 of JavaHelp software. The most visible benefit of the upgrade is better merging of TOC and index. NetBeans IDE uses the Unite-Append merge type for the table of contents and the Sort merge type for the index. These merge types are set in the master help set and propogate to any help sets that merge into the product, unless those help sets override them with other merge types. For more information on merge types, see the JavaHelp release notes.

The biggest resulting impact for module authors is the need to more carefully design TOCs and indexes so that entries from different help sets merge comprehensibly for users. Here are some general tips and rules of thumb:

Making the Help Set Known to the IDE

In order to use the result help set within the IDE at runtime, a couple of things need to be added to various files associated with the module. These are outlined in part in the reference documentation. This description assumes you are using a NetBeans module project.

A module's help set should be defined by creating a package-info.java file in the same package as the help set and adding the @HelpSetRegistration annotation to it. You will want to specify a position for the help set; this mainly affects the order into which help sets are merged into the table of contents.

Where to Put Help Files in the Module Source

Help files should be kept under the regular src subdirectory off of the module root directory. Like source code, all JavaHelp documentation must be placed into a globally unique package to avoid conflicts. If two modules put help files into the same package, it will result in broken links. You should therefore use a distinctive "package" name prefix. It is conventional to use module.code.name.base.docs, e.g. for a module named org.netbeans.modules.foo, place the JavaHelp into org.netbeans.modules.foo.docs (plus perhaps subpackages).

Additional Notes

This section includes any additional comments or issues regarding Help for IDE modules.

Questions or comments? Send to nbdev.