by Java Q&a Experts

Help tips in Swing?

news
Oct 20, 19993 mins

How to add menu help tips functionality to Swing

Q: Is it possible for Swing to support menu help tips?

Since it is so common in the PC world to have applications whose menus display help text in a status area whenever one of the items in the menu is activated, I was surprised to see that this functionality was missing from the Swing menu set. Is there some way to create this functionality without having to subclass the beegeebers out of Swing? I’ve gotten it to work for pure JMenuItems:

  myMenu.add(new JMenuItem("Save As..."));

by subclassing JMenuItems and overriding the menuSelectionChanged() method. Unfortunately this won’t work for menu items created when an action is added to a menu (which returns a pure JMenuItem), nor will it work for JCheckBoxMenuItems or JRadioButtonMenuItems.

I’m sure there are many developers who would like to provide this spiffy functionality, so if you could provide a way of doing this I’m sure you’d make a lot of people happy.

I’m using JDK 1.2.2 FCS.

A: The Java Q&A experts recommend that, instead of using inheritance, you use delegation to create a generic adapter class in order to achieve your desired functionality.

This adapter class will take a JMenuItem, a string of help text to display, and a JLabel to be the status bar in which to display the message. When a menu item is activated, the adapter will cause the appropriate text to display in the status bar.

The difficult aspect of your problem: how to figure out what event to listen for? It turns out that a ChangeEvent is generated when menu items activate and deactivate. Java’s term for this is arming the menu item. Using this information, the following adapter class can be written:

class MenuHelpTextAdapter implements ChangeListener
{
   private JMenuItem menuItem;
   private String helpText;
   private JLabel statusBar;
   public MenuHelpTextAdapter(JMenuItem menuItem, String helpText, JLabel statusBar)
   {
      this.menuItem = menuItem;
      this.helpText = helpText;
      this.statusBar = statusBar;
      menuItem.addChangeListener(this);
   }
   public void stateChanged(ChangeEvent evt)
   {
      if (menuItem.isArmed())
         statusBar.setText(helpText);
      else
         statusBar.setText(" ");
   }
}

The code that creates the adapters for the menu items is quite simple:

   new MenuHelpTextAdapter(item1, "Help text for item 1", statusBar);
   new MenuHelpTextAdapter(item2, "Item 2 info", statusBar);

Using this adapter — as an inner class in this case — we can create a complete sample program:

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
public class StatusBarTest
{
   JLabel statusBar;
   JMenuItem item1;
   JMenuItem item2;
   private void init()
   {
      JFrame frame = new JFrame("Status Bar Test");
      JMenuBar menuBar = new JMenuBar();
      frame.setJMenuBar(menuBar);
      JMenu fileMenu = new JMenu("File");
      menuBar.add(fileMenu);
      item1 = new JMenuItem("Item 1");
      item2 = new JMenuItem("Item 2");
      fileMenu.add(item1);
      fileMenu.add(item2);
      Container contentPane = frame.getContentPane();
      contentPane.setLayout(new BorderLayout());
      contentPane.add("Center", new JButton("Main application area"));
      statusBar = new JLabel(" ");
      contentPane.add("South", statusBar);
      new MenuHelpTextAdapter(item1, "Help text for item 1", statusBar);
      new MenuHelpTextAdapter(item2, "Item 2 info", statusBar);
      frame.setSize(400,400);
      frame.setVisible(true);
   }
   public static void main(String[] args)
   {
      StatusBarTest t = new StatusBarTest();
      t.init();
   }
   class MenuHelpTextAdapter implements ChangeListener
   {
      private JMenuItem menuItem;
      private String helpText;
      private JLabel statusBar;
       public MenuHelpTextAdapter(JMenuItem menuItem, String helpText,
       JLabel statusBar)
     {
         this.menuItem = menuItem;
         this.helpText = helpText;
         this.statusBar = statusBar;
         menuItem.addChangeListener(this);
      }
      public void stateChanged(ChangeEvent evt)
      {
         if (menuItem.isArmed())
            statusBar.setText(helpText);
         else
            statusBar.setText(" ");
      }
   }
}

Random Walk Computing is the largest Java/CORBA consulting boutique in New York, focusing on solutions for the financial enterprise. Known for their leading-edge Java expertise, Random Walk consultants publish and speak about Java in some of the most respected forums in the world.