Menus are unique in that, by convention, they aren't placed with the other components in the UI. Instead, a menu usually appears either in a menu bar or as a popup menu. A menu bar contains one or more menus and has a customary, platform-dependent location — usually along the top of a window. A popup menu is a menu that is invisible until the user makes a platform-specific mouse action, such as pressing the right mouse button, over a popup-enabled component. The popup menu then appears under the cursor.
The following figure shows many menu-related components: a menu bar, menus, menu items, radio button menu items, check box menu items, and separators. As you can see, a menu item can have either an image or text, or both. You can also specify other properties, such as font and color.
The rest of this section teaches you about the menu components and tells you how to use various menu features:
MenuLookDemo.java
.
Other required files are listed in the
example index.
//Where the GUI is created: JMenuBar menuBar; JMenu menu, submenu; JMenuItem menuItem; JRadioButtonMenuItem rbMenuItem; JCheckBoxMenuItem cbMenuItem; //Create the menu bar. menuBar = new JMenuBar(); //Build the first menu. menu = new JMenu("A Menu"); menu.setMnemonic(KeyEvent.VK_A); menu.getAccessibleContext().setAccessibleDescription( "The only menu in this program that has menu items"); menuBar.add(menu); //a group of JMenuItems menuItem = new JMenuItem("A text-only menu item", KeyEvent.VK_T); menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_1, ActionEvent.ALT_MASK)); menuItem.getAccessibleContext().setAccessibleDescription( "This doesn't really do anything"); menu.add(menuItem); menuItem = new JMenuItem("Both text and icon", new ImageIcon("images/middle.gif")); menuItem.setMnemonic(KeyEvent.VK_B); menu.add(menuItem); menuItem = new JMenuItem(new ImageIcon("images/middle.gif")); menuItem.setMnemonic(KeyEvent.VK_D); menu.add(menuItem); //a group of radio button menu items menu.addSeparator(); ButtonGroup group = new ButtonGroup(); rbMenuItem = new JRadioButtonMenuItem("A radio button menu item"); rbMenuItem.setSelected(true); rbMenuItem.setMnemonic(KeyEvent.VK_R); group.add(rbMenuItem); menu.add(rbMenuItem); rbMenuItem = new JRadioButtonMenuItem("Another one"); rbMenuItem.setMnemonic(KeyEvent.VK_O); group.add(rbMenuItem); menu.add(rbMenuItem); //a group of check box menu items menu.addSeparator(); cbMenuItem = new JCheckBoxMenuItem("A check box menu item"); cbMenuItem.setMnemonic(KeyEvent.VK_C); menu.add(cbMenuItem); cbMenuItem = new JCheckBoxMenuItem("Another one"); cbMenuItem.setMnemonic(KeyEvent.VK_H); menu.add(cbMenuItem); //a submenu menu.addSeparator(); submenu = new JMenu("A submenu"); submenu.setMnemonic(KeyEvent.VK_S); menuItem = new JMenuItem("An item in the submenu"); menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_2, ActionEvent.ALT_MASK)); submenu.add(menuItem); menuItem = new JMenuItem("Another item"); submenu.add(menuItem); menu.add(submenu); //Build second menu in the menu bar. menu = new JMenu("Another Menu"); menu.setMnemonic(KeyEvent.VK_N); menu.getAccessibleContext().setAccessibleDescription( "This menu does nothing"); menuBar.add(menu); ... frame.setJMenuBar(theJMenuBar);
As the code shows,
to set the menu bar for a JFrame
,
you use the setJMenuBar
method.
To add a JMenu
to a JMenuBar
,
you use the add(JMenu)
method.
To add menu items and submenus to a JMenu
,
you use the add(JMenuItem)
method.
Other methods
in the preceding code include setAccelerator
and
setMnemonic
,
which are discussed a little later in
Enabling Keyboard Operation.
The setAccessibleDescription
method
is discussed in
How to Support Assistive Technologies.
JMenuItem
,
you can listen for action events
(just as you would for a
JButton
).
To detect when the user chooses a JRadioButtonMenuItem
,
you can listen for either action events or
item events,
as described in
How to Use Radio Buttons.
For JCheckBoxMenuItem
s,
you generally listen for item events,
as described in
How to Use Check Boxes.
Here is the code that implements the event handling:
public class MenuDemo ... implements ActionListener, ItemListener { ... public MenuDemo() { //...for each JMenuItem instance: menuItem.addActionListener(this); ... //for each JRadioButtonMenuItem: rbMenuItem.addActionListener(this); ... //for each JCheckBoxMenuItem: cbMenuItem.addItemListener(this); ... } public void actionPerformed(ActionEvent e) { //...Get information from the action event... //...Display it in the text area... } public void itemStateChanged(ItemEvent e) { //...Get information from the item event... //...Display it in the text area... }
A mnemonic is a key that
makes an already visible menu item be chosen.
For example, in MenuDemo
the first menu has the mnemonic A,
and its second menu item has the mnemonic B.
This means that, when you run MenuDemo
with the Java look and feel,
pressing the Alt and A keys makes
the first menu appear.
While the first menu is visible,
pressing the B key (with or without Alt)
makes the second menu item be chosen.
A menu item generally displays its mnemonic
by underlining the first occurrence of the mnemonic character
in the menu item's text,
as the following snapshot shows.
An accelerator is a key combination
that causes a menu item to be chosen,
whether or not it's visible.
For example, pressing the Alt and 2 keys in MenuDemo
makes the first item in the first menu's submenu be chosen,
without bringing up any menus.
Only leaf menu items — menus that don't bring up other menus —
can have accelerators.
The following snapshot shows how the Java look and feel
displays a menu item that has an accelerator.
You can specify a mnemonic either when constructing the menu item
or with the setMnemonic
method.
To specify an accelerator,
use the setAccelerator
method.
Here are examples of setting mnemonics and accelerators:
//Setting the mnemonic when constructing a menu item: menuItem = new JMenuItem("A text-only menu item", KeyEvent.VK_T); //Setting the mnemonic after creation time: menuItem.setMnemonic(KeyEvent.VK_T); //Setting the accelerator: menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_T, ActionEvent.ALT_MASK));
KeyEvent
constant corresponding to the key the user should press.
To specify an accelerator you must use a
KeyStroke
object,
which combines a key
(specified by a KeyEvent
constant)
and a modifier-key mask
(specified by an
ActionEvent
constant).
JPopupMenu
), you must register a mouse listener
on each component
that the popup menu should be associated with.
The mouse listener must detect
user requests that the popup menu be brought up.
The exact gesture that should bring up a popup menu varies by look and feel. In Microsoft Windows, the user by convention brings up a popup menu by releasing the right mouse button while the cursor is over a component that is popup-enabled. In the Java look and feel, the customary trigger is either pressing the right mouse button (for a popup that goes away when the button is released) or clicking it (for a popup that stays up).
//...where instance variables are declared: JPopupMenu popup; //...where the GUI is constructed: //Create the popup menu. popup = new JPopupMenu(); menuItem = new JMenuItem("A popup menu item"); menuItem.addActionListener(this); popup.add(menuItem); menuItem = new JMenuItem("Another popup menu item"); menuItem.addActionListener(this); popup.add(menuItem); //Add listener to components that can bring up popup menus. MouseListener popupListener = new PopupListener(); output.addMouseListener(popupListener); menuBar.addMouseListener(popupListener); ... class PopupListener extends MouseAdapter { public void mousePressed(MouseEvent e) { maybeShowPopup(e); } public void mouseReleased(MouseEvent e) { maybeShowPopup(e); } private void maybeShowPopup(MouseEvent e) { if (e.isPopupTrigger()) { popup.show(e.getComponent(), e.getX(), e.getY()); } } }
Popup menus have a few interesting implementation details. One is that every menu has an associated popup menu. When the menu is activated, it uses its associated popup menu to show its menu items.
Another detail is that a popup menu itself
uses another component
to implement the window containing the menu items.
Depending on the circumstances under which
the popup menu is displayed,
the popup menu might implement its "window" using
a lightweight component (such as a JPanel
),
a "mediumweight" component (such as a
Panel
),
or a heavyweight window (something that inherits from
Window
).
Lightweight popup windows are more efficient than
heavyweight windows but, prior to the
Java SE Platform 6 Update 12 release, they didn't work well
if you had any heavyweight components inside your GUI.
Specifically, when the lightweight popup's display area
intersects the heavyweight component's display area,
the heavyweight component is drawn on top.
This is one of the reasons that, prior to the 6u12 release,
we recommended against mixing heavyweight and lightweight components.
If you are using an older release and absolutely need to use a heavyweight
component in your GUI, then you can invoke
JPopupMenu.setLightWeightPopupEnabled(false)
to disable lightweight popup windows.
For information on mixing components in the 6u12 release and later, please see
Mixing Heavyweight and Lightweight Components.
Because menus are made up of ordinary Swing components,
you can easily customize them.
For example,
you can add any lightweight component
to a JMenu
or JMenuBar
.
And because JMenuBar
uses
BoxLayout
,
you can customize a menu bar's layout
just by adding invisible components to it.
Here is an example
of adding a glue component to a menu bar,
so that
the last menu is at the right edge of the menu bar:
//...create and add some menus... menuBar.add(Box.createHorizontalGlue()); //...create the rightmost menu... menuBar.add(rightMenu);
Here's the modified menu layout that MenuGlueDemo displays:
Another way of changing the look of menus
is to change the layout managers used to control them.
For example, you can change a menu bar's layout manager
from the default left-to-right BoxLayout
to something such as GridLayout
.
Here's a picture of the menu layout that MenuLayoutDemo
creates:
Constructor or Method | Purpose |
---|---|
JMenuBar() | Creates a menu bar. |
JMenu add(JMenu) | Adds the menu to the end of the menu bar. |
void setJMenuBar(JMenuBar) JMenuBar getJMenuBar() (in JApplet ,
JDialog ,
JFrame ,
JInternalFrame ,
JRootPane )
|
Sets or gets the menu bar of an applet, dialog, frame, internal frame, or root pane. |
Constructor or Method | Purpose |
---|---|
JMenu() JMenu(String) JMenu(Action) |
Creates a menu.
The string specifies the text to display for the menu.
The Action specifies the text
and other properties of the menu (see
How to Use Actions).
|
JMenuItem add(JMenuItem)
JMenuItem add(String) |
Adds a menu item to the current end of the menu.
If the argument is a string,
then the menu automatically creates a JMenuItem object
that displays the specified text.
Version Note: Before 1.3, the only way to associate an |
void addSeparator() | Adds a separator to the current end of the menu. |
JMenuItem insert(JMenuItem, int)
void insert(String, int) void insertSeparator(int) |
Inserts a menu item or separator into the menu
at the specified position.
The first menu item is at position 0,
the second at position 1, and so on.
The JMenuItem
and String arguments are treated the same
as in the corresponding add methods.
|
void remove(JMenuItem) void remove(int) void removeAll() |
Removes the specified item(s) from the menu. If the argument is an integer, then it specifies the position of the menu item to be removed. |
Constructor or Method | Purpose |
---|---|
JPopupMenu() JPopupMenu(String) |
Creates a popup menu. The optional string argument specifies the title that a look and feel might display as part of the popup window. |
JMenuItem add(JMenuItem)
JMenuItem add(String) |
Adds a menu item to the current end of the popup menu.
If the argument is a string,
then the menu automatically creates a JMenuItem object
that displays the specified text.
Version Note: Before 1.3, the only way to associate an |
void addSeparator() | Adds a separator to the current end of the popup menu. |
void insert(Component, int) | Inserts a menu item into the menu
at the specified position.
The first menu item is at position 0,
the second at position 1, and so on.
The Component argument specifies
the menu item to add.
|
void remove(int) void removeAll() |
Removes the specified item(s) from the menu. If the argument is an integer, then it specifies the position of the menu item to be removed. |
static void setLightWeightPopupEnabled(boolean) | By default, Swing implements a menu's window
using a lightweight component.
This can cause problems if you use any heavyweight components
in your Swing program,
as described in Bringing Up a Popup Menu.
(This is one of several reasons to avoid using heavyweight components.)
As a workaround, invoke
JPopupMenu.setLightWeightPopupEnabled(false) .
|
void show(Component, int, int) | Display the popup menu at the specified x,y position (specified in that order by the integer arguments) in the coordinate system of the specified component. |
Constructor or Method | Purpose |
---|---|
JMenuItem() JMenuItem(String) JMenuItem(Icon) JMenuItem(String, Icon) JMenuItem(String, int) JMenuItem(Action) |
Creates an ordinary menu item.
The icon argument, if present,
specifies the icon that the menu item should display.
Similarly, the string argument
specifies the text that the menu item should display.
The integer argument specifies the keyboard mnemonic
to use. You can specify any of the relevant VK
constants defined in the
KeyEvent class.
For example, to specify the A key,
use KeyEvent.VK_A .
The constructor with the |
JCheckBoxMenuItem() JCheckBoxMenuItem(String) JCheckBoxMenuItem(Icon) JCheckBoxMenuItem(String, Icon) JCheckBoxMenuItem(String, boolean) JCheckBoxMenuItem(String, Icon, boolean) |
Creates a menu item that looks and acts like a check box.
The string argument, if any, specifies
the text that the menu item should display.
If you specify true for the boolean argument,
then the menu item is initially selected (checked).
Otherwise, the menu item is initially unselected.
|
JRadioButtonMenuItem() JRadioButtonMenuItem(String) JRadioButtonMenuItem(Icon) JRadioButtonMenuItem(String, Icon) JRadioButtonMenuItem(String, boolean) JRadioButtonMenuItem(Icon, boolean) JRadioButtonMenuItem(String, Icon, boolean) |
Creates a menu item that looks and acts like a radio button.
The string argument, if any, specifies
the text that the menu item should display.
If you specify true for the boolean argument,
then the menu item is initially selected.
Otherwise, the menu item is initially unselected.
|
void setState(boolean) boolean getState() (in JCheckBoxMenuItem )
|
Set or get the selection state of a check box menu item. |
void setEnabled(boolean) | If the argument is true, enable the menu item. Otherwise, disable the menu item. |
void setMnemonic(int) | Set the mnemonic that enables keyboard navigation to
the menu or menu item. Use one of the VK
constants defined in the KeyEvent class.
|
void setAccelerator(KeyStroke) | Set the accelerator that activates the menu item. |
void setActionCommand(String) | Set the name of the action performed by the menu item. |
void addActionListener(ActionListener) void addItemListener(ItemListener) |
Add an event listener to the menu item. See Handling Events from Menu Items for details. |
void setAction(Action) | Set the Action
associated with the menu item.
See
How to Use Actions for details.
|
Many of the preceding methods are inherited from
AbstractButton .
See The Button API
for information about other useful methods
that AbstractButton provides.
|
Example | Where Described | Notes |
---|---|---|
MenuLookDemo
|
This section (Creating Menus) | A simple example that creates all kinds of menus except popup menus, but doesn't handle events from the menu items. |
MenuDemo
|
This section (Handling Events from Menu Items) | Adds event handling to MenuLookDemo .
|
PopupMenuDemo
|
This section (Bringing Up a Popup Menu) | Adds popup menus to MenuDemo .
|
MenuGlueDemo
|
This section (Customizing Menu Layout) | Demonstrates affecting menu layout by adding an invisible components to the menu bar. |
MenuLayoutDemo
|
This section (Customizing Menu Layout) | Implements sideways-opening menus arranged in a vertical menu bar. |
MenuSelectionManagerDemo
|
— | Adds highlight detection to MenuDemo.
To see this feature, click a menu and then move the mouse
over any menu item or submenu.
Once per second, the text area will be updated with information
about the currently highlighted menu item,
not to be confused with the menu item that the user
eventually chooses.
This demo uses the default
MenuSelectionManager , which tracks the state of the menu hierarchy.
|
ActionDemo
|
How to Use Actions | Uses Action objects to implement menu items
that duplicate functionality provided by tool bar buttons.
|
Framework
|
— | Brings up multiple identical frames, each with a menu in its menu bar. |
InternalFrameDemo
|
How to Use Internal Frames | Uses a menu item to create windows. |