JAVA Swing Menu Example
1. Introduction
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 choices include, combo boxes, lists, radio buttons, spinners, and tool bars.
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.
Table Of Contents
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.
2. JAVA Swing Menu
2.1 Setup
Popular Java Editors:
To write your java programs you will need a text editor. There are even more sophisticated IDE available in the market. But for now, you can consider one of the following:
- Notepad: On Windows machine you can use any simple text editor like Notepad TextPad.
- NetBeans: is a Java IDE that is open source and free which can be downloaded from http://www.netbeans.org/index.html.
- Eclipse: is also a java IDE developed by the eclipse open source community and can be downloaded from http://www.eclipse.org
Prerequisite
This example is developed on Eclipse therefore a compatible Eclipse IDE is required to be installed on the system.
We also need WindowBuilder tool to be installed on Eclipse IDE for the easiness of the work. To learn how to install WindowBuilder tool please visit the Setup section 2.1 of the following link click here.
2.2 Creating Menus
The following code creates the menus shown near the beginning of this menu section. Because this code has no event handling, the menus do nothing useful except to look as 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.
SwingMenuExample.java
//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.
Menu items, like other components, can be in at most one container. If you try to add a menu item to a second menu, the menu item will be removed from the first menu before being added to the second.
2.3 Handling Events from Menu Items
To detect when the user chooses a 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. For JCheckBoxMenuItems, you generally listen for item events.
The handler i.e. actionPerformed, for an event generated by a button will look like this:
SwingMenuExample.java
b1 = new JButton("Disable middle button", leftButtonIcon); b2 = new JButton("Middle button", middleButtonIcon); b3 = new JButton("Enable middle button", rightButtonIcon); //Listen for actions on buttons 1 and 3. b1.addActionListener(this); b3.addActionListener(this); public void actionPerformed(ActionEvent e) { if ("disable".equals(e.getActionCommand())) { b2.setEnabled(false); b1.setEnabled(false); b3.setEnabled(true); } else { b2.setEnabled(true); b1.setEnabled(true); b3.setEnabled(false); } }
Check boxes are similar to radio buttons but their selection model is different, by convention. Any number of check boxes in a group — none, some, or all — can be selected. A group of radio buttons, on the other hand, can only have one button selected.
The handler i.e. itemStateChanged, for an event generated by a checkbox will look like this:
SwingMenuExample.java
/In initialization code: chinButton = new JCheckBox("Chin"); chinButton.setMnemonic(KeyEvent.VK_C); chinButton.setSelected(true); glassesButton = new JCheckBox("Glasses"); glassesButton.setMnemonic(KeyEvent.VK_G); glassesButton.setSelected(true); hairButton = new JCheckBox("Hair"); hairButton.setMnemonic(KeyEvent.VK_H); hairButton.setSelected(true); teethButton = new JCheckBox("Teeth"); teethButton.setMnemonic(KeyEvent.VK_T); teethButton.setSelected(true); //Register a listener for the check boxes. chinButton.addItemListener(this); glassesButton.addItemListener(this); hairButton.addItemListener(this); teethButton.addItemListener(this); ... public void itemStateChanged(ItemEvent e) { ... Object source = e.getItemSelectable(); if (source == chinButton) { //...make a note of it... } else if (source == glassesButton) { //...make a note of it... } else if (source == hairButton) { //...make a note of it... } else if (source == teethButton) { //...make a note of it... } if (e.getStateChange() == ItemEvent.DESELECTED) //...make a note of it... ... updatePicture(); }
Radio buttons are groups of buttons in which, by convention, only one button at a time can be selected. The Swing releases supports radio buttons with the JRadioButton and ButtonGroup classes. To put a radio button in a menu, use the JRadioButtonMenuItem class.
The handler i.e. actionPerformed, for an event generated by a Radio Button will look like this:
SwingMenuExample.java
//In initialization code: //Create the radio buttons. JRadioButton birdButton = new JRadioButton(birdString); birdButton.setMnemonic(KeyEvent.VK_B); birdButton.setActionCommand(birdString); birdButton.setSelected(true); JRadioButton catButton = new JRadioButton(catString); catButton.setMnemonic(KeyEvent.VK_C); catButton.setActionCommand(catString); JRadioButton dogButton = new JRadioButton(dogString); dogButton.setMnemonic(KeyEvent.VK_D); dogButton.setActionCommand(dogString); JRadioButton rabbitButton = new JRadioButton(rabbitString); rabbitButton.setMnemonic(KeyEvent.VK_R); rabbitButton.setActionCommand(rabbitString); JRadioButton pigButton = new JRadioButton(pigString); pigButton.setMnemonic(KeyEvent.VK_P); pigButton.setActionCommand(pigString); //Group the radio buttons. ButtonGroup group = new ButtonGroup(); group.add(birdButton); group.add(catButton); group.add(dogButton); group.add(rabbitButton); group.add(pigButton); //Register a listener for the radio buttons. birdButton.addActionListener(this); catButton.addActionListener(this); dogButton.addActionListener(this); rabbitButton.addActionListener(this); pigButton.addActionListener(this); ... public void actionPerformed(ActionEvent e) { picture.setIcon(new ImageIcon("images/" + e.getActionCommand() + ".gif")); }
2.4 Enabling Keyboard Operation
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 SwingMenuExample the first menu has the mnemonic A, and its second menu item has the mnemonic B. This means that, when you run SwingMenuExample 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.
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 SwingMenuExample 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.
Alt+2 advertises this menu item’s 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
SwingMenuExample.java
//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));
As you can see, you set a mnemonic by specifying the 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).
2.5 Bringing Up a Popup Menu
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.
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).
SwingMenuExample.java
//...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.
2.6 Customizing Menu Layout
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:
SwingMenuExample.java
//...create and add some menus... menuBar.add(Box.createHorizontalGlue()); //...create the rightmost menu... menuBar.add(rightMenu);
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
.
3. The Menu API
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
3.1 Creating and Setting Up Menu Bars
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() | Sets or gets the menu bar of an applet, dialog, frame, internal frame, or root pane. |
3.2 Creating and Populating Menus
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 |
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. |
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. |
3.3 Creating, Populating, and Controlling 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(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. |
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. |
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. |
3.4 Implementing Menu Items
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 Action parameter sets the menu item’s Action, causing the menu item’s properties to be initialized from the Action. |
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() | 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. |
void setAction(Action) | Set the Action associated with the menu item |
4. Output
The Output of the code when executed will look like the one below.
5. Download The Source Code
This was an example of creation of JAVA Swing Menu.
You can download the full source code of this example here: SwingMenuExample