A
JMenu
is a standard pull-down menu with a
fixed name. Menus can hold other menus as submenu items, enabling you
to implement complex menu structures. In Swing, menus are first-class
components, just like everything else. You can place them wherever a
component would go. Another class,
JMenuBar
, holds menus in a horizontal bar. Menu
bars are real components, too, so you can place them wherever you
want in a container: top, bottom, or middle. But in the middle of a
container, it usually makes more sense to use a
JComboBox
rather than some kind of menu.
Menu items may have associated images and shortcut keys; there are even menu items that look like checkboxes and radio buttons. Menu items are really a kind of button. Like buttons, menu items fire action events when they are selected. You can respond to menu items by registering action listeners with them.
There are two ways to use the keyboard with menus. The first is called mnemonics . A mnemonic is one character in the menu name. If you hold down the Alt key and type a menu’s mnemonic, the menu will drop down, just as if you had clicked on it with the mouse. Menu items may also have mnemonics. Once a menu is dropped down, you can select individual items in the same way.
Menu items may also have accelerators . An accelerator is a key combination that selects the menu item, whether or not the menu that contains it is showing. A common example is the accelerator Ctrl-C, which is frequently used as a shortcut for the Copy item in the Edit menu.
The following example demonstrates several different features of menus. It creates a menu bar with three different menus. The first, Utensils , contains several menu items, a submenu, a separator, and a Quit item that includes both a mnemonic and an accelerator. The second menu, Spices, contains menu items that look and act like checkboxes. Finally, the Cheese menu demonstrates how radio button menu items can be used.
This application is shown in Figure 14.4 with one of its menus dropped down. Choosing Quit from the menu (or pressing Ctrl-Q) removes the window. Give it a try.
//file: DinnerMenu.java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class DinnerMenu extends JFrame { public DinnerMenu( ) { super("DinnerMenu v1.0"); setSize(200, 200); setLocation(200, 200); // create the Utensils menu JMenu utensils = new JMenu("Utensils"); utensils.setMnemonic(KeyEvent.VK_U); utensils.add(new JMenuItem("Fork")); utensils.add(new JMenuItem("Knife")); utensils.add(new JMenuItem("Spoon")); JMenu hybrid = new JMenu("Hybrid"); hybrid.add(new JMenuItem("Spork")); hybrid.add(new JMenuItem("Spife")); hybrid.add(new JMenuItem("Knork")); utensils.add(hybrid); utensils.addSeparator( ); // do some fancy stuff with the Quit item JMenuItem quitItem = new JMenuItem("Quit"); quitItem.setMnemonic(KeyEvent.VK_Q); quitItem.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_Q, Event.CTRL_MASK)); quitItem.addActionListener(new ActionListener( ) { public void actionPerformed(ActionEvent e) { System.exit(0); } }); utensils.add(quitItem); // create the Spices menu JMenu spices = new JMenu("Spices"); spices.setMnemonic(KeyEvent.VK_S); spices.add(new JCheckBoxMenuItem("Thyme")); spices.add(new JCheckBoxMenuItem("Rosemary")); spices.add(new JCheckBoxMenuItem("Oregano", true)); spices.add(new JCheckBoxMenuItem("Fennel")); // create the Cheese menu JMenu cheese = new JMenu("Cheese"); cheese.setMnemonic(KeyEvent.VK_C); ButtonGroup group = new ButtonGroup( ); JRadioButtonMenuItem rbmi; rbmi = new JRadioButtonMenuItem("Regular", true); group.add(rbmi); cheese.add(rbmi); rbmi = new JRadioButtonMenuItem("Extra"); group.add(rbmi); cheese.add(rbmi); rbmi = new JRadioButtonMenuItem("Blue"); group.add(rbmi); cheese.add(rbmi); // create a menu bar and use it in this JFrame JMenuBar menuBar = new JMenuBar( ); menuBar.add(utensils); menuBar.add(spices); menuBar.add(cheese); setJMenuBar(menuBar); } public static void main(String[] args) { JFrame f = new DinnerMenu( ); f.addWindowListener(new WindowAdapter( ) { public void windowClosing(WindowEvent we) { System.exit(0); } }); f.setVisible(true); } }
Yes, we know. Quit doesn’t belong in the Utensils menu. If it’s driving you crazy, you can go back and add a File menu as an exercise when we’re through.
Creating menus is pretty simple work. You create a
JMenu
object, specifying the menu’s
title.[43] Then you just add
JMenuItem
s to the JMenu
. You
can also add JMenu
s to a JMenu
;
they show up as
submenus.
This is shown in the creation of the Utensils menu:
JMenu utensils = new JMenu("Utensils"); utensils.setMnemonic(KeyEvent.VK_U); utensils.add(new JMenuItem("Fork")); utensils.add(new JMenuItem("Knife")); utensils.add(new JMenuItem("Spoon")); JMenu hybrid = new JMenu("Hybrid"); hybrid.add(new JMenuItem("Spork")); hybrid.add(new JMenuItem("Spife")); hybrid.add(new JMenuItem("Knork")); utensils.add(hybrid);
In the second line, we set the
mnemonic
for this menu using a constant defined in the KeyEvent
class.
You can add those pretty separator lines with a single call:
utensils.addSeparator( );
The Quit menu item has some bells and whistles we should explain. First, we create the menu item and set its mnemonic, just as we did before for the Utensils menu:
JMenuItem quitItem = new JMenuItem("Quit"); quitItem.setMnemonic(KeyEvent.VK_Q);
Now we want to create an
accelerator
for the menu item. We do this with the help of a class called
KeyStroke
:
quitItem.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_Q, Event.CTRL_MASK));
Finally, to actually do something in response to the menu item, we register an action listener:
quitItem.addActionListener(new ActionListener( ) { public void actionPerformed(ActionEvent e) { System.exit(0); } });
Our action listener exits the application when the Quit item is selected.
Creating the Spices
menu is just as easy, except
that we use JCheckBoxMenuItem
s instead of regular
JMenuItem
s. The result is a menu full of items
that behave like checkboxes.
The next menu, Cheese
, is a little more tricky. We want the
items to be radio buttons, but we need to place them in a
ButtonGroup
to ensure they are mutually exclusive.
Each item, then, is created, added to the button group, and added to
the menu itself.
The final step is to place the menus we’ve just created in a
JMenuBar
. This is simply a component that lays
out menus in a horizontal bar. We have two options for adding it to
our JFrame
. Since the JMenuBar
is a real component, we could add it to the content pane of the
JFrame
. Instead, we use a convenience method
called setJMenuBar( )
,
which automatically places the JMenuBar
at the top
of the frame’s content pane. This saves us the trouble of
altering the layout or size of the content pane; it is adjusted to
coexist peacefully with the
menu bar.
Get Learning Java now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.