About Menus
Essentially, all menus in Java are represented by two classes: Jmenu and JmenuItem.
A JMenuItem represents an actual selectable menu item. For example, the “New” and “Open” items in Figure 1 are JMenuItem objects. A JMenu is a container for JMenuItems that, when selected, pops up a window displaying the JMenuItems . For example, the “File,” “Edit,” and “Help” items in Figure 1 are JMenu objects.
JMenu and JMenuItem objects.
Now let’s consider how JMenu and JMenuItem objects are created. We’ll start with the JMenuItem object, and later we’ll add instances of it to the JMenu object.
JMenuItem
The JMenuItem class has five constructors:
Table 1. JMenuItem Constructors
Constructor |
Description |
JMenuItem() |
Creates a menuItem with no set text or icon |
JMenuItem(Icon icon) |
Creates a menuItem with an icon |
JMenuItem(String text) |
Creates a menuItem with text |
JMenuItem(String text, Icon icon) |
Creates a menuItem with the supplied text and icon |
JMenuItem(String text, int mnemonic) |
Creates a menuItem with the specified text and keyboard mnemonic |
From Table 1, you can see that a JMenuItem can contain a combination of a text element, an icon element, and a mnemonic element (hot key). The text element is specified by a java.lang.String object, which is pretty self-explanatory. The icon element is specified by an object that implements the javax.swing.Icon interface; the most commonly used implementation of this interface with respect to JMenuItem construction is the javax.swing.ImageIcon object. The ImageIcon object has numerous constructors (refer to the Java 2 SDK documentation), but some specify an image filename(for a .jpg or .gif file) in order to simplify its use, and some specify a Uniform Resource Locator (URL) from which to obtain the image. The mnemonic element is specified by an integer that represents the keystroke for the mnemonic. Constants are defined in the java.awt.event.KeyEvent class to represent these keys. For example, in Figure 1 the “F” in “File” and the “N” in “New” represent keyboard mnemonics, and the “Ctrl+N” is known as an accelerator. We will talk more about this more specifically when we reach the JMenuItem methods.
Below are a few sample JMenuItem objects:
// Constructor 1 JMenuItem fileSave = new JMenuItem(); // Constructor 2 JMenuItem fileOpen = new JMenuItem( new ImageIcon( “fileOpen.gif” ) ); // Constructor 3 JMenuItem fileNew = new JMenuItem( “New” ); // Constructor 4 JMenuItem fileClose = new JMenuItem( “Close”, new ImageIcon( “fileClose.gif” ) ); // Constructor 5 JMenuItem fileExit = new JMenuItem( “Exit”, KeyEvent.VK_X );
The JMenuItem class has a few methods of interest. You can refer to the Java 2 SDK documentation for the full description, but Table 2 shows some highlights.
Table 2. JMenuItem Methods
Method |
Description |
void setMnemonic(int) |
Sets the keyboard mnemonic for the JMenuItem (inherited from javax.swing.AbstractButton) |
int getMnemonic() |
Retrieves the keyboard mnemonic for the JMenuItem (inherited from javax.swing.AbstractButton) |
void setAccelerator(KeyStroke) |
Sets the key combination that invokes the JMenuItem object’s action listeners without navigating the menu hierarchy |
KeyStroke getAccelerator() |
Retrieves the KeyStroke that is the accelerator for the JMenuItem |
void addMenuKeyListener(MenuKeyListener) |
Adds a MenuKeyListener to the menu item |
void addActionListener(ActionListener) |
Adds an ActionListener to the button (inherited from javax.swing.AbstractButton) |
While you are already familiar with the concept of the keyboard mnemonic, the accelerator is new to you; an accelerator is a key stroke that selects a menu item without displaying the menu (for example “Ctrl-N” is the accelerator that invokes File->New action from anywhere in the application). To contrast this with a keyboard mnemonic, the hotkey invokes the menu item when the menu is already displayed (for example you can hit Alt-F to invoke the “File” menu and then “Alt-N” to invoke the “New” action).
The last two methods in Table 2 address the event handling that is available to the JMenuItem class: javax.swing.event.MenuKeyListener and java.awt.event.ActionListener. (Note that there are other events handlers for the JMenuItem class that you can learn about in the Java 2 SDK documentation; however, these two will suffice for our discussion.) Table 3 shows the MenuKeyListener methods , and Table 4 shows the ActionListener methods.
Table 3. MenuKeyListener Methods
Method |
Description |
void menuKeyPressed(MenuKeyEvent) |
Invoked when a key has been pressed |
void menuKeyReleased(MenuKeyEvent) |
Invoked when a key has been released |
void menuKeyTyped(MenuKeyEvent) |
Invoked when a key has been typed |
Table 4. ActionListener Methods
Method |
Description |
void actionPerformed(ActionEvent) |
Invoked when an action occurs |
The MenuKeyListener interface will alert you when keyboard menu events occur, but it will not alert you of mouse selections; the main purpose of this is to allow you to gain fine control of the menu during keyboard activities. The ActionListener interface will alert you of both keyboard and mouse menu events, and will be the event handler of choice in our JWord application.
JRadioButtonMenuItem and JCheckBoxMenuItem
Two special types of JMenuItem class derivations exist: javax.swing.JRadioButtonMenuItem and javax.swing.JCheckBoxMenuItem. As you may have already surmised, these enable you to use radio buttons and check boxes within your menus.
A radio button group is a collection of buttons where one, and only one button can exist in a selected state at any given time. For example, in Figure 2, only one window in our word processor can have the input focus (or, be the current document we are editing) so that will be displayed and controlled by the set of Window radio buttons. A javax.swing.ButtonGroup object must manage the selection state of JRadioButtonMenuItem class items ; when a JRadioButtonMenuItem object is selected, it is the responsibility of the ButtonGroup to select that item and to deselect all others in the group.
JRadioButtonMenuItem objects.
A check box, on the other hand, is simply a button that can be in either a checked state or an unchecked state. For example, in Figure 3, both a toolbar and a status bar can be displayed at the same time (or neither can be, for that matter), so their visibility can be specified and controlled by check boxes. A JCheckBoxMenuItem manages its own selection state and does not require the aid of the ButtonGroup class; its state is either checked or unchecked, and it toggles it every time it is selected.
JCheckBoxMenuItem objects.
Both the JRadioButtonMenuItem and JCheckBoxMenuItem classes have the same constructors as the JMenuItem class, with the addition of constructors that specify their initial selection state. Tables 5 and 6 show those additional constructors:
Table 5. JRadioButtonMenuItem Constructors
Constructor |
Description |
JradioButtonMenuItem |
Creates a radio button menu item with the specified image and selection state, but no text. |
JradioButtonMenuItem |
Creates a radio button menu item with the specified text and selection state. |
JradioButtonMenuItem |
Creates a radio button menu item that has the specified text, image, and selection state. |
Table 6. JCheckBoxMenuItem Constructors
Constructor |
Description |
JcheckBoxMenuItem (String, boolean selected) |
Creates a check box menu item with the specified text and selection state. |
JcheckBoxMenuItem (String, Icon, boolean selected) |
Creates a check box menu item with the specified text, icon, and selection state. |
Before I show you an example, we need to discussthe ButtonGroup class. The ButtonGroup class has an empty constructor, and we will be interested in one of its methods: add(AbstractButton b). This method adds a button to the button group. The following listing shows an example of code for the constructing and initializing of a couple of JRadioButtonMenuItem and JCheckBoxRadioButton objects, and how to make use of the ButtonGroup.
// Create two JCheckBoxMenuItem objects, the first selected and the second deselected JCheckBoxMenuItem viewToolbar = new JCheckBoxMenuItem( "Toolbar", true ); JCheckBoxMenuItem viewStatusbar = new JCheckBoxMenuItem( "Status Bar", false ); // Create two JRadioButtonMenuItems JRadioButtonMenuItem showWindow1 = new JRadioButtonMenuItem( “Window 1”, true ); JRadioButtonMenuItem showWindow2 = new JRadioButtonMenuItem( “Window 2” ); // Create a ButtonGroup to manage the radio buttons ButtonGroup buttonGroup = new ButtonGroup(); // Add the radio buttons to the button group buttonGroup.add( showWindow1 ); buttonGroup.add( showWindow2 );
With these JMenuItem (and derivatives) under your belt, you’re ready to learn how to use them.
JMenu
As you learned earlier, the JMenu class is actually just a container in which to hold JMenuItem and other JMenu objects. Take a look at Table 7 for the JMenu constructors:
Table 7. JMenu Constructors
Constructor |
Description |
JMenu() |
Creates a new JMenu with no text |
JMenu(String s) |
Creates a new JMenu with the supplied string as its text |
JMenu(String s, boolean b) Creates a new JMenu with the supplied string as its text and specified as a tear-off menu or not |
These constructors are fairly self-explanatory (except for the tear-off boolean value), but this is not implemented as of the Java 2 SDK v1.3. Do not worry about it right now, but keep it in the back of your mind for later versions of the SDK.
The JMenu class has a plethora of methods to which you can refer in the Java 2 SDK documentation; refer to Table 8 for some highlights:
Table 8. JMenu Methods
Method |
Description |
JMenuItem add(Action) |
Creates a new menu item attached to the specified Action object and appends it to the end of this menu |
Component add(Component) |
Appends a component to the end of this menu |
JMenuItem add(JMenuItem) |
Appends a menu item to the end of this menu |
JMenuItem add(String) |
Creates a new menu item with the specified text and appends it to the end of this menu |
void addMenuListener (MenuListener) |
Adds a listener for menu events |
void removeMenuListener (MenuListener) |
Removes a listener from menu events |
void addSeparator() |
Appends a new separator to the end of the menu |
JMenuItem insert(Action, int pos) |
Inserts a new menu item attached to the specified Action object at a given position |
JMenuItem insert(JMenuItem, int pos) |
Inserts the specified JMenuitem at a given position |
void insert(String, int pos) |
Inserts a new menu item with the specified text at a given position |
void insertSeparator(int index) |
Inserts a separator at the specified position |
The important methods to note here are those that add and insert elements into the JMenu; the ones that we will concern ourselves with are add(JMenuItem) and insert(JMenuItem, int pos). A JMenu is actually derived from JMenuItem, so it is perfectly legal to add a JMenu to a JMenu in order to create nested menus. Another method that might have caught your eye is the addSeparator() method; it adds a line between menu items that is similar to the line between “Close” and “Save” in Figure 1.
Finally, you might be interested in the MenuListener interface and the corresponding add/remove methods. MenuListener events are not as exciting as you might suspect; they refer to menu selection, not menu item selection. Typically you will be interested in handling menu item selections (for example, the user chooses “Exit” from the “File” menu) and you will simply ignore menu selections (for example, the user chooses the “File” menu.)
Take a look at the following listing for an example of how you might build a help menu.
// Create a menu item JMenu menuHelp = new JMenu( “Help” ); // Create a couple menu items JMenuItem helpContents = new JMenuItem( “Contents” ); JMenuItem helpAbout = new JMenuItem( “About” ); // Add the menu items to the menu menuHelp.add( helpContents ); menuHelp.addSeparator(); menuHelp.add( helpAbout );
Now that we have built a menu, what do we do with it?