Start of Tutorial > Start of Trail > Start of Lesson | Search |
A menu provides a space-saving way to let the user choose one of several options. Other components with which the user can make a one-of-many choice include combo boxes, lists, radio buttons, and tool bars. If any of your menu items performs an action that is duplicated by another menu item or by a tool-bar button, then in addition to this section you should read How to Use Actions.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 the Swing components that implement each part of the menu system.
[PENDING: Add labels: JMenuBar
,JMenu
,JMenuItem
,JCheckBoxMenuItem
,JRadioButtonMenuItem
, andJSeparator
. Leave outJPopupMenu
.]The rest of this section teaches you about the menu components and tells you how to use various menu features:
- The menu component hierarchy
- Creating menus
- Handling events from menu items
- Enabling keyboard operation
- Bringing up a popup menu
- Customizing menu layout
- The Menu API
- Examples that use menus
Here is a picture of the inheritance hierarchy for the menu-related classes:As the figure shows, menu items (including menus) are simply buttons. You might be wondering how a menu, if it's only a button, shows its menu items. The answer is that when a menu is activated, it automatically brings up a popup menu that displays the menu items.
The following code creates the menus shown near the beginning of this menu section. The bold lines of code create and connect the menu objects; the other code sets up or customizes the menu objects. You can find the entire program inMenuLookDemo.java
. To run the program, you need to have the following image file:images/middle.gif
.
Note: Because this code has no event handling, the menus do nothing useful except look like they should. If you run the example, you'll notice that despite the lack of custom event handling, menus and submenus appear when they should, and the check boxes and radio buttons respond appropriately when the user chooses them.//in the constructor for a JFrame subclass: JMenuBar menuBar; JMenu menu, submenu; JMenuItem menuItem; JCheckBoxMenuItem cbMenuItem; JRadioButtonMenuItem rbMenuItem; ... //Create the menu bar. menuBar = new JMenuBar(); setJMenuBar(menuBar); //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);As the code shows, to set the menu bar for a
JFrame
, you use thesetJMenuBar
method. To add aJMenu
to aJMenuBar
, you use theadd(JMenu)
method. To add menu items and submenus to aJMenu
, you use theadd(JMenuItem)
method. Other methods in the preceding code includesetAccelerator
andsetMnemonic
, which are discussed in Enabling Keyboard Operation. ThesetAccessibleDescription
method is discussed in How to Support Assistive Technologies.
To detect when the user selects aJMenuItem
, you can listen for action events (just as you would for aJButton
). To detect when the user selects aJRadioButtonMenuItem
, you can listen for either action events or item events, as described in How to Use Radio Buttons. ForJCheckBoxMenuItem
s, you generally listen for item events, as described in How to Use Check Boxes.The following picture shows a program that adds event detection to the preceding example. The program's code is in
MenuDemo.java
. LikeMenuLookDemo
,MenuDemo
uses theimages/middle.gif
image file.Here is the code that implements the event handling: For examples of handling action and item events, see the button, radio button, and check box sections, as well as the list of examples at the end of this section.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... }
Menus support two kinds of keyboard alternatives: mnemonics and accelerators. Mnemonics offer a way to use the keyboard to navigate the menu hierarchy, increasing the accessibility of programs. Accelerators, on the other hand, offer keyboard shortcuts to bypass navigating the menu hierarchy. Mnemonics are for all users; accelerators are for power users.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 runMenuDemo
with the Java Look & 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 & 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 thesetAccelerator
method. Here are examples of setting mnemonics and accelerators:As you can see, you set a mnemonic by specifying the//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 aKeyStroke
object, which combines a key (specified by aKeyEvent
constant) and a modifier-key mask (specified by anActionEvent
constant).
To bring up a popup menu (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. On Windows and Motif platforms, the user brings up a popup menu by pressing the right mouse button while the cursor is over a component that is popup-enabled.The mouse listener brings up the popup menu by invoking the
show
method on the appropriateJPopupMenu
instance. The following code, taken fromPopupMenuDemo.java
, shows how to create and show popup menus://...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 aPanel
), or a heavyweight window (something that inherits fromWindow
).Lightweight popup windows are more efficient than heavyweight windows, but they don't work well if you have 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 we recommend against mixing heavyweight and lightweight components. If you absolutely need to use a heavyweight component in your GUI, then you can invoke
JPopupMenu.setLightWeightPopupEnabled(false)
to disable lightweight popup windows. For details, see Mixing Heavy and Light Components, an article in The Swing Connection.
Because menus are made up of ordinary Swing components, you can easily customize them. For example, you can add any lightweight component to aJMenu
orJMenuBar
. And becauseJMenuBar
usesBoxLayout
, 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:
Here is a picture of the result, which you can duplicate by compiling and running//...create and add some menus... menuBar.add(Box.createHorizontalGlue()); //...create the rightmost menu... menuBar.add(rightMenu);MenuGlueDemo.java
: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 asGridLayout
. You can also change how an activated menu or other popup menu lays out its items, asMenuLayoutDemo.java
demonstrates. Here's a picture of the menu layout thatMenuLayoutDemo
creates:
The following tables list the commonly used menu constructors and methods. The API for using menus falls into these categories:
- Creating and Setting Up Menu Bars
- Creating and Populating Menus
- Creating, Populating, and Controlling Popup Menus
- Implementing Menu Items
Creating and Setting Up Menu Bars Constructor or Method Purpose JMenuBar()
Creates a menu bar. JMenu add(JMenu)
Creates a menu bar. void setJMenuBar(JMenuBar)
JMenuBar getJMenuBar()
(inJApplet
,JDialog
,JFrame
,JInternalFrame
,JRootPane
)Sets or gets the menu bar of an applet, dialog, frame, internal frame, or root pane.
Creating and Populating Menus Constructor or Method Purpose JMenu()
JMenu(String)Creates a menu. The string specifies the text to display for the menu. JMenuItem add(JMenuItem)
JMenuItem add(Action)
JMenuItem add(String)Adds a menu item to the current end of the menu. If the argument is an Action
object, then the menu creates a menu item as described in How to Use Actions. If the argument is a string, then the menu automatically creates aJMenuItem
object that displays the specified text.void addSeparator()
Adds a separator to the current end of the menu. JMenuItem insert(JMenuItem, int)
JMenuItem insert(Action, 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
,Action
, andString
arguments are treated the same as in the correspondingadd
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.
Creating and Populating Popup Menus 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(Action)
JMenuItem add(String)Adds a menu item to the current end of the popup menu. If the argument is an Action
object, then the popup menu creates a menu item as described in How to Use Actions. If the argument is a string, then the menu automatically creates aJMenuItem
object that displays the specified text.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(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. 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.
Implementing Menu Items Constructor or Method Purpose JMenuItem()
JMenuItem(String)
JMenuItem(Icon)
JMenuItem(String, Icon)
JMenuItem(String, int)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, useKeyEvent.VK_A
.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()
(inJCheckBoxMenuItem
)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. Many of the preceding methods are inherited from AbstractButton
. See The Button API for information about other useful methods thatAbstractButton
provides.
Menus are used in a few Swing examples.
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
.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. 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.
Start of Tutorial > Start of Trail > Start of Lesson | Search |