Users don’t read your documentation. It doesn’t matter how complex an application may be; they try to figure out for themselves how to accomplish a given task and, when everything else fails, they prefer to ask someone else rather than read the documentation.
So it's up to us, as software developers, to make our applications as easy and intuitive as possible. In this article, I'll present one of the several techniques you can use to achieve that goal—supplying hints to help the user understand your application.
Guiding the user
One of the most popular techniques to make applications easier to use is to present small clues—hints—about each element of the user interface. The Swing Framework provides an implementation of that concept in the form of tool tips. You can set a tool tip for any Swing component by calling its setToolTipText method.
Once the tool tip is set, whenever the mouse pointer enters the component, a small window with the text (hint) is displayed over the component for a while. The purpose of the hint is to give the user an idea of what the component does, how to use it, or whatever information you feel is useful.
Although using tool tips is straightforward, there are some drawbacks. Tool tips are appropriate just for very small hints, since the Swing implementation does not break the text. You must wait until the tool tip is displayed and read it before it's gone. Hints are somewhat intrusive since they are displayed over the component. For that reason, they don't look good on some components such as menu items.
Another commonly used approach is to display hints in the application’s status bar. The concept is the same; that is, the hint is displayed when the mouse pointer enters the component and is removed when it exits. But since hints are displayed in an area reserved specifically for tips, this alternative does not suffer from the disadvantages of tool tips.
Implementing mouse-over hints
Unfortunately, Swing doesn't provide built-in support for status-bar hints; however, implementing status-bar hints yourself is not difficult. Basically, all you need to do is register a mouse listener for each component you want to show a hint, and implement the mouseEntered and mouseExited methods of the MouseListener interface.
The mouseEntered method shows the hint for the component, and the mouseExited removes it. The source of the event can be used to identify the component and select the hint to be displayed, so that you don’t need to register a different mouse listener for each component.
MouseOverHintManager (Listing A) is a reusable class that provides an implementation for status-bar hints. Using it is straightforward. Just construct an instance of MouseOverHintManager passing a JLabel instance that will be used to display the hints; call the method addHintFor to set a hint for each component you want; and call the method enableHints for the user interface top container (window, frame, dialog box, etc.).
The MouseOverHintManager implementation closely follows the former outline presented. The addHintFor method receives, as parameters, a Component reference and its corresponding hint, saving them in a Map for later retrieval. Notice that hints are saved in a WeakHashMap instance so that they are automatically garbage-collected as needed when there are no more references to the corresponding component. For that reason, there's no need for a method to remove hints.
The enableHints method adds the MouseOverHintManager as a mouse listener for all components, subcomponents, menu elements, etc., of the top container passed as parameter.
The mouseEntered method uses the source of the event, that is, the component the mouse pointer has entered, as a key to retrieve its hint from the Map and display it at the JLabel saved by the constructor. The mouseExited method just clears the hint by setting the JLabel to blank.
Beware of special cases
There are some small tricks worth noting so that hints display as expected. First, notice that the mouseEntered method gets the hint for the component that generated the event. If the component doesn't have a hint, mouseEntered checks if its parent does.
This process continues until the top component is reached or a hint is found, which is displayed to the user. This logic allows you to set a hint for a container, like a panel, and have all of its children display the same hint, or set one hint for the parent and a different one for the child.
Another trick is the getHintFor method, which is called by mouseEntered to get a hint for a component. If the component it receives as a parameter doesn't have a hint, it tests for some special cases. If the component is a JLabel or JTableHeader, the method returns the hint of the component that the JLabel is attached to or the hint of the Jtable, respectively. That way, you don’t need to set a hint twice for a component and then again for its label, even though they are displayed as separate components.
Putting hints to work
MouseOverHintDemo (Listing B) is a simple example that demonstrates how to use the MouseOverHintManager class. It just creates a JFrame with a status bar to show the hints and some of the most used Swing components.
The example is straightforward; it just creates all components of the user interface, sets hints for them, builds the application’s main window, and calls the MouseOverHintManager.enableHints. Notice that it is important to call enableHints as the last operation after building the user interface, so that enableHints can register mouse listeners for all components. This is necessary so that MouseOverHintManager receives mouse events from all components and can select the appropriate hint for each case.
Running the example displays a simple window with several controls. Move the mouse over the components and menu elements to see a hint displayed for each in the application’s status bar. Notice that the two radio buttons display the same hint, which is actually set at their parent panel.
Hints are an important technique to make applications easier to use. Status bar hints are an alternative to Swing tool tips and are easy to implement.
Users don't read your documentation. So it's up to us, as software developers, to make our applications as easy and intuitive as possible. If you're writing a Java GUI, here's one easy way to help—adding status-bar hints.