Menus make selection easier and are widely used in window applications. Java provides five classes that implement menus: JMenuBar , JMenu , JMenuItem , JCheckBoxMenuItem , and JRadioButtonMenuItem .
JMenuBar is a top-level menu component used to hold menus. A menu consists of menu items that the user can select (or toggle on or off). A menu item can be an instance of JMenuItem , JCheckBoxMenuItem , or JRadioButtonMenuItem . Menu items can be associated with icons, keyboard mnemonics , and keyboard accelerators. Menu items can be separated using separators.
The sequence of implementing menus in Java is as follows :
Create a menu bar and associate it with a frame or an applet by using the setJMenuBar method. For example, the following code creates a frame and a menu bar, and sets the menu bar in the frame:
JFrame frame = new JFrame(); frame.setSize( 300 , 200 ); frame.setVisible( true ); JMenuBar jmb = new JMenuBar(); frame.setJMenuBar(jmb); // Attach a menu bar to a frame
Create menus and associate them with the menu bar. You can use the following constructor to create a menu:
public JMenu(String label)
Here is an example of creating menus:
JMenu fileMenu = new JMenu( "File" ); JMenu helpMenu = new JMenu( "Help" );
This creates two menus labeled File and Help , as shown in Figure 29.1(a). The menus will not be seen until they are added to an instance of JMenuBar , as follows:
jmb.add(fileMenu); jmb.add(helpMenu);
Create menu items and add them to the menus.
fileMenu.add( new JMenuItem( "New" )); fileMenu.add( new JMenuItem( " Open " )); fileMenu.addSeparator(); fileMenu.add( new JMenuItem( "Print" )); fileMenu.addSeparator(); fileMenu.add( new JMenuItem( "Exit" ));
This code adds the menu items New, Open, a separator bar, Print, another separator bar, and Exit, in this order, to the File menu, as shown in Figure 29.1(b). The addSeparator() method adds a separator bar in the menu.
3.1. | Creating submenu items. You can also embed menus inside menus so that the embedded menus become submenus. Here is an example: JMenu softwareHelpSubMenu = new JMenu( "Software" ); JMenu hardwareHelpSubMenu = new JMenu( "Hardware" ); helpMenu.add(softwareHelpSubMenu); helpMenu.add(hardwareHelpSubMenu); softwareHelpSubMenu.add( new JMenuItem( "Unix" )); softwareHelpSubMenu.add( new JMenuItem( "NT" )); softwareHelpSubMenu.add( new JMenuItem( "Win95" )); This code adds two submenus, softwareHelpSubMenu and hardwareHelpSubMenu , in helpMenu . The menu items Unix , NT , and Win95 are added to softwareHelpSubMenu (see Figure 29.1(c)). |
3.2. | Creating check box menu items. You can also add a JCheckBoxMenuItem to a JMenu . JCheckBoxMenuItem is a subclass of JMenuItem that adds a Boolean state to the JMenuItem , and displays a check when its state is true. You can click a menu item to turn it on or off. For example, the following statement adds the check box menu item Check it (see Figure 29.2(a)): helpMenu.add( new JCheckBoxMenuItem( "Check it" )); |
3.3. | Creating radio button menu items. You can also add radio buttons to a menu, using the JRadioButtonMenuItem class. This is often useful when you have a group of mutually exclusive choices in the menu. For example, the following statements add a submenu named Color and a set of radio buttons for choosing a color (see Figure 29.2(b)): JMenu colorHelpSubMenu = new JMenu( "Color" ); helpMenu.add(colorHelpSubMenu); JRadioButtonMenuItem jrbmiBlue, jrbmiYellow, jrbmiRed; colorHelpSubMenu.add(jrbmiBlue = new JRadioButtonMenuItem( "Blue" )); colorHelpSubMenu.add(jrbmiYellow = new JRadioButtonMenuItem( "Yellow" )); colorHelpSubMenu.add(jrbmiRed = new JRadioButtonMenuItem( "Red" )); ButtonGroup btg = new ButtonGroup(); btg.add(jrbmiBlue); btg.add(jrbmiYellow); btg.add(jrbmiRed); |
The menu items generate ActionEvent . Your listener class must implement the ActionListener and the actionPerformed handler to respond to the menu selection.
The menu components JMenu , JMenuItem , JCheckBoxMenuItem , and JRadioButtonMenuItem have the icon and mnemonic properties. For example, using the following code, you can set icons for the New and Open menu items, and set keyboard mnemonics for File, Help, New, and Open:
JMenuItem jmiNew, jmiOpen; fileMenu.add(jmiNew = new JMenuItem( "New" )); fileMenu.add(jmiOpen = new JMenuItem( "Open" )); jmiNew.setIcon( new ImageIcon( "image/new.gif" )); jmiOpen.setIcon( new ImageIcon( "image/open.gif" )); helpMenu.setMnemonic( 'H' ); fileMenu.setMnemonic( 'F' ); jmiNew.setMnemonic( 'N' ); jmiOpen.setMnemonic( 'O' );
The new icons and mnemonics are shown in Figure 29.2(c). You can also use JMenuItem constructors like the ones that follow to construct and set an icon or mnemonic in one statement:
public JMenuItem(String label, Icon icon); public JMenuItem(String label, int mnemonic);
By default, the text is at the right of the icon. Use setHorizontalTextPosition(SwingConstants.LEFT) to set the text to the left of the icon.
To select a menu, press the ALT key and the mnemonic key. For example, press ALT+F to select the File menu, and then press ALT+O to select the Open menu item. Keyboard mnemonics are useful, but only let you select menu items from the currently open menu. Key accelerators, however, let you select a menu item directly by pressing the CTRL and accelerator keys. For example, by using the following code, you can attach the key CTRL+O to the Open menu item:
jmiOpen.setAccelerator(KeyStroke.getKeyStroke (KeyEvent.VK_O, ActionEvent.CTRL_MASK));
The setAccelerator method takes a KeyStroke object. The static method getKeyStroke in the KeyStroke class creates an instance of the keystroke. VK_O is a constant representing the O key, and CTRL_MASK is a constant indicating that the CTRL key is associated with the keystroke.
Note
As shown in Figure 15.3, AbstractButton is the superclass for JButton and JMenuItem , and JMenuItem is a superclass for JCheckBoxMenuItem , JMenu , and JRadioButtonMenuItem . The menu components are very similar to buttons. |
This section gives an example that creates a user interface to perform arithmetic. The interface contains labels and text fields for Number 1, Number 2, and Result. The Result text field displays the result of the arithmetic operation between Number 1 and Number 2. Figure 29.3 contains a sample run of the program.
Here are the major steps in the program (Listing 29.1):
1. | Create a menu bar and set it in the applet. Create the menus Operation and Exit, and add them to the menu bar. Add the menu items Add, Subtract, Multiply, and Divide under the Operation menu, and add the menu item Close under the Exit menu. |
2. | Create a panel to hold labels and text fields, and place the panel in the center of the applet. |
3. | Create a panel to hold the four buttons labeled Add, Subtract, Multiply, and Divide. Place the panel in the south of the applet. |
4. | Implement the actionPerformed handler to process the events from the menu items and the buttons. |
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 public class MenuDemo extends JApplet { 6 // Text fields for Number 1, Number 2, and Result 7 private JTextField jtfNum1, jtfNum2, jtfResult; 8 9 // Buttons "Add", "Subtract", "Multiply" and "Divide" 10 private JButton jbtAdd, jbtSub, jbtMul, jbtDiv; 11 12 // Menu items "Add", "Subtract", "Multiply", "Divide" and "Close" 13 private JMenuItem jmiAdd, jmiSub, jmiMul, jmiDiv, jmiClose; 14 15 public MenuDemo() { 16 // Create menu bar 17 JMenuBar jmb = new JMenuBar(); 18 19 // Set menu bar to the applet 20 setJMenuBar(jmb); 21 22 // Add menu "Operation" to menu bar 23 JMenu operationMenu = new JMenu( "Operation" ); 24 operationMenu.setMnemonic( 'O' ); 25 jmb.add(operationMenu); 26 27 // Add menu "Exit" to menu bar 28 JMenu exitMenu = new JMenu( "Exit" ); 29 exitMenu.setMnemonic( 'E' ); 30 jmb.add(exitMenu); 31 32 // Add menu items with mnemonics to menu "Operation" 33 operationMenu.add(jmiAdd= new JMenuItem( "Add" , 'A' )); 34 operationMenu.add(jmiSub = new JMenuItem( "Subtract" , 'S' )); 35 operationMenu.add(jmiMul = new JMenuItem( "Multiply" , 'M' )); 36 operationMenu.add(jmiDiv = new JMenuItem( "Divide" , 'D' )); 37 exitMenu.add(jmiClose = new JMenuItem( "Close" , 'C' )); 38 39 // Set keyboard accelerators 40 jmiAdd.setAccelerator( 41 KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK)); 42 jmiSub.setAccelerator( 43 KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)); 44 jmiMul.setAccelerator( 45 KeyStroke.getKeyStroke(KeyEvent.VK_M, ActionEvent.CTRL_MASK)); 46 jmiDiv.setAccelerator( 47 KeyStroke.getKeyStroke(KeyEvent.VK_D, ActionEvent.CTRL_MASK)); 48 49 // Panel p1 to hold text fields and labels 50 JPanel p1 = new JPanel( new FlowLayout()); 51 p1.add( new JLabel( "Number 1" )); 52 p1.add(jtfNum1 = new JTextField( 3 )); 53 p1.add( new JLabel( "Number 2" )); 54 p1.add(jtfNum2 = new JTextField( 3 )); 55 p1.add( new JLabel( "Result" )); 56 p1.add(jtfResult = new JTextField( 4 )); 57 jtfResult.setEditable( false ); 58 59 // Panel p2 to hold buttons 60 JPanel p2 = new JPanel( new FlowLayout()); 61 p2.add(jbtAdd = new JButton( "Add" )); 62 p2.add(jbtSub = new JButton( "Subtract" )); 63 p2.add(jbtMul = new JButton( "Multiply" )); 64 p2.add(jbtDiv = new JButton( "Divide" )); 65 66 // Add panels to the frame 67 setLayout( new BorderLayout()); 68 add(p1, BorderLayout.CENTER); 69 add(p2, BorderLayout.SOUTH); 70 71 // Register listeners 72 jbtAdd.addActionListener( new ActionListener() { 73 public void actionPerformed(ActionEvent e) { 74 calculate( '+' ); 75 } 76 }); 77 jbtSub.addActionListener( new ActionListener() { 78 public void actionPerformed(ActionEvent e) { 79 calculate( '-' ); 80 } 81 }); 82 jbtMul.addActionListener( new ActionListener() { 83 public void actionPerformed(ActionEvent e) { 84 calculate( '*' ); 85 } 86 }); 87 jbtDiv.addActionListener( new ActionListener() { 88 public void actionPerformed(ActionEvent e) { 89 calculate( '/' ); 90 } 91 }); 92 jmiAdd.addActionListener( new ActionListener() { 93 public void actionPerformed(ActionEvent e) { 94 calculate( '+' ); 95 } 96 }); 97 jmiSub.addActionListener( new ActionListener() { 98 public void actionPerformed(ActionEvent e) { 99 calculate( '-' ); 100 } 101 }); 102 jmiMul.addActionListener( new ActionListener() { 103 public void actionPerformed(ActionEvent e) { 104 calculate( '*' ); 105 } 106 }); 107 jmiDiv.addActionListener( new ActionListener() { 108 public void actionPerformed(ActionEvent e) { 109 calculate( '/' ); 110 } 111 }); 112 jmiClose.addActionListener( new ActionListener() { 113 public void actionPerformed(ActionEvent e) { 114 System.exit( ); 115 } 116 }); 117 } 118 119 /** Calculate and show the result in jtfResult */ 120 private void calculate( char operator) { 121 // Obtain Number 1 and Number 2 122 int num1 = (Integer.parseInt(jtfNum1.getText().trim())); 123 int num2 = (Integer.parseInt(jtfNum2.getText().trim())); 124 int result = ; 125 126 // Perform selected operation 127 switch (operator) { 128 case '+' : result = num1 + num2; 129 break ; 130 case '-' : result = num1 - num2; 131 break ; 132 case '*' : result = num1 * num2; 133 break ; 134 case '/' : result = num1 / num2; 135 } 136 137 // Set result in jtfResult 138 jtfResult.setText(String.valueOf(result)); 139 } 140 } |
The program creates a menu bar, jmb , which holds two menus: operationMenu and exitMenu (lines 17 “30). The operationMenu contains four menu items for doing arithmetic: Add, Subtract, Multiply, and Divide. The exitMenu contains the menu item Close for exiting the program. The menu items in the Operation menu are created with keyboard mnemonics and accelerators.
The user enters two numbers in the number fields. When an operation is chosen from the menu, its result, involving two numbers, is displayed in the Result field. The user can also click the buttons to perform the same operation.
The private method calculate(char operator) (lines 120 “139) retrieves operands from the text fields in Number 1 and Number 2, applies the binary operator on the operands, and sets the result in the Result text field.
Note
The menu bar is usually attached to the window using the setJMenuBar method. However, like any other component, it can be placed in a container. For instance, you can place a menu bar in the south of the container with BorderLayout . |