Main Page

Previous Next

Adding a Menu to a Window

As we have already discussed, a JMenuBar object represents the menu bar that is placed at the top of a window. You can add JMenu or JMenuItem objects to a JMenuBar object and these will be displayed on the menu bar. A JMenu object is a menu item with a label that can display a pull-down menu when clicked. A JMenuItem object represents a simple menu item with a label that results in some program action when clicked – such as opening a dialog. A JMenuItem can have an icon in addition to, or instead of, a String label. Each item on the pull-down menu for an object of type JMenu, can be an object of either type JMenu, JMenuItem, JCheckBoxMenuItem, or JRadioButtonMenuItem.

A JCheckBoxMenuItem is a simple menu item with a checkbox associated with it. The checkbox can be checked and unchecked and typically indicates that that menu item was selected last time the pull-down menu was displayed. You can also add separators in a pull-down menu. These are simply bars to separate one group of menu items from another. A JRadioButtonMenuItem is a menu item much like a radio button in that it is intended to be one of a group of like menu items added to a ButtonGroup object. Both JCheckBoxMenuItem and JRadioButtonMenuItem objects can have icons.

Creating JMenu and JMenuItem

To create a JMenu object you call a JMenu class constructor and pass a String object to it that contains the label for the menu. For example, to create a File menu you would write:

JMenu fileMenu = new JMenu("File");

Creating a JMenuItem object is much the same:

JMenuItem openMenu = new JMenuItem("Open");

If you create a JCheckboxMenuItem object by passing just a String argument to the constructor, the object will represent an item that is initially unchecked. For example, you could create an unchecked item with the following statement:

JCheckboxMenuItem circleItem = new JCheckboxMenuItem("Circle");

Another constructor for this class allows you to set the check mark by specifying a second argument of type boolean. For example:

JCheckboxMenuItem lineItem = new JCheckboxMenuItem("Line", true);

This creates an item with the label, Line, which will be checked initially. You can, of course, also use this constructor to explicitly specify that you want an item to be unchecked by setting the second argument to false.

A JRadioButtonMenuItem object is created in essentially the same way:

JRadioButtonMenuItem item = new JRadioButtonMenuItem("Curve", true);

This creates a radio button menu item that is selected.

If you want to use a menu bar in your application window, you must create your window as a JFrame object, since the JFrame class incorporates the capability to manage a menu bar. You can also add a menu bar to JDialog and JApplet objects. Let's see how we can create a menu on a menu bar.

Creating a Menu

To create a window with a menu bar, we will define our own window class as a subclass of JFrame. This will be a much more convenient way to manage all the details of the window compared to using a JFrame object directly as we have been doing up to now. By extending the JFrame class, we can add our own members that will customize a JFrame window to our particular needs. We can also override the methods defined in the JFrame class to modify their behavior, if necessary.

We will be adding functionality to this example over several chapters, so create a directory for it with the name Sketcher. This program will be a window-based sketching program that will enable you to create sketches using lines, circles, curves, and rectangles, and to annotate them with text. By building an example in this way, you will gradually create a much larger Java program than the examples seen so far, and you will also gain experience of combining many of the capabilities of javax.swing and other standard packages in a practical situation.

Try It Out – Building a Menu

To start with, we will have two class files in the Sketcher program. The file will contain the method main() where execution of the application will start, and the file will contain the class defining the application window.

We will define a preliminary version of our window class as:

// Frame for the Sketcher application
import javax.swing.*;

public class SketchFrame extends JFrame {
  // Constructor
  public SketchFrame(String title) {
    setTitle(title);                             // Set the window title

    setJMenuBar(menuBar);                        // Add the menu bar to the window

    JMenu fileMenu = new JMenu("File");          // Create File menu
    JMenu elementMenu = new JMenu("Elements");   // Create Elements menu

    menuBar.add(fileMenu);                       // Add the file menu
    menuBar.add(elementMenu);                    // Add the element menu

  private JMenuBar menuBar = new JMenuBar();     // Window menu bar

After you have entered this code into a new file, save the file in the Sketcher directory as

Next, you can enter the code for the Sketcher class in a separate file:

// Sketching application
import java.awt.Toolkit;
import java.awt.Dimension;

public class Sketcher {
  static SketchFrame window;                     // The application window

  public static void main(String[] args) {
    window = new SketchFrame("Sketcher");        // Create the app window
    Toolkit theKit = window.getToolkit();        // Get the window toolkit
    Dimension wndSize = theKit.getScreenSize();  // Get screen size

    // Set the position to screen center & size to half screen size
    window.setBounds(wndSize.width/4, wndSize.height/4,        // Position
                      wndSize.width/2, wndSize.height/2);      // Size


Save this file as in the Sketcher directory. If you compile and run Sketcher you should see the window shown.

How It Works

The Sketcher class has a SketchFrame variable as a data member, which we will use to store the application window object. We must declare this variable as static as there will be no instances of the Sketcher class around. The variable, window, is initialized in the method main() that is called when program execution begins. Once the window object exists, we set the size of the window based on the screen size in pixels, which we obtain using the Toolkit object. This is exactly the same process that we saw earlier in this chapter. Finally in the method main(), we call the setVisible() method for the window object with the argument true to display the application window.

In the constructor for the SketchFrame class, we could pass the title for the window to the superclass constructor to create the window with the title bar directly. However, later when we have developed the application a bit more we will want to add to the title, so we call the setTitle() member to set the window title here. Next we call the setJMenuBar() method that is inherited from the JFrame class, to specify menuBar as the menu bar for the window. To define the two menus that are to appear on the menu bar, we create one JMenu object with the label "File" and another with the label "Elements" – these labels will be displayed on the menu bar. We add the fileMenu and elementMenu objects to the menu bar by calling the add() method for the menuBar object.

The instance variable that we have defined in the SketchFrame class represents the menu bar. Both the menu items on the menu bar are of type JMenu, so we need to add pull-down menus to each of them. The File menu will provide the file input, output, and print options, and we will eventually use the Elements menu to choose the kind of geometric figure we want to draw. Developing the menu further, we can now add the menu items.

Adding Items to a Pull-Down Menu

Both the items on the menu bar need a pull-down menu – they can't do anything by themselves because they are of type JMenu. You use a version of the add() method defined in the JMenu class to add items to a pull-down menu.

The simplest version creates a menu item with the label that you pass as an argument. For example:

JMenuItem newMenu = fileMenu.add("New");               // Add the menu item "New" 

This will create a JMenuItem object with the label "New", add it to the menu for the fileMenu item, and return a reference to it. You will need the reference to react to the user clicking the item.

You can also create the JMenuItem object explicitly and use the second version of the add() method to add it:

JMenuItem newMenu = new JMenuItem("New");              // Create the item
fileMenu.add(newMenu);                                 // and add it to the menu

You can operate on menu items by using the following methods defined in the JMenuItem class:



void setEnabled(boolean b)

If b has the value true the menu item is enabled. If b has the value false the menu item is disabled. The default state is enabled.

void setText(String label)

Sets the menu item label to the string stored in the label.

String getText()

Returns the current menu item label.

Since the JMenu class is a subclass of JMenuItem, these methods also apply to JMenu objects. To add a separator to a pull-down menu you call the addSeparator() method for the JMenu object.

Let's now create the pull-down menus for the File and Element menus on the menu bar in the Sketcher application, and try out some of the menu items.

Try It Out – Adding Pull-Down Menus

We can change the definition of our SketchFrame class to do this:

// Frame for the Sketcher application
import javax.swing.*;

public class SketchFrame extends JFrame {
  // Constructor
  public SketchFrame(String title) {
    setTitle(title);                             // Set the window title

    setJMenuBar(menuBar);                        // Add the menu bar to the window

    JMenu fileMenu = new JMenu("File");          // Create File menu
    JMenu elementMenu = new JMenu("Elements");   // Create Elements menu

    // Construct the file pull down menu
    newItem = fileMenu.add("New");                // Add New item
    openItem = fileMenu.add("Open");              // Add Open item
    closeItem = fileMenu.add("Close");            // Add Close item
    fileMenu.addSeparator();                      // Add separator
    saveItem = fileMenu.add("Save");              // Add Save item
    saveAsItem = fileMenu.add("Save As...");      // Add Save As item
    fileMenu.addSeparator();                      // Add separator
    printItem = fileMenu.add("Print");            // Add Print item

    // Construct the Element pull-down menu
    elementMenu.add(lineItem = new JRadioButtonMenuItem("Line", true));
    elementMenu.add(rectangleItem = new JRadioButtonMenuItem("Rectangle", false));
    elementMenu.add(circleItem = new JRadioButtonMenuItem("Circle", false));
    elementMenu.add(curveItem = new JRadioButtonMenuItem("Curve", false));
    ButtonGroup types = new ButtonGroup();


    elementMenu.add(redItem = new JCheckBoxMenuItem("Red", false));
    elementMenu.add(yellowItem = new JCheckBoxMenuItem("Yellow", false));
    elementMenu.add(greenItem = new JCheckBoxMenuItem("Green", false));
    elementMenu.add(blueItem = new JCheckBoxMenuItem("Blue", true));

    menuBar.add(fileMenu);                        // Add the file menu
    menuBar.add(elementMenu);                     // Add the element menu

  private JMenuBar menuBar = new JMenuBar();      // Window menu bar

  // File menu items
  private JMenuItem newItem,  openItem,   closeItem,
                    saveItem, saveAsItem, printItem;

  // Element menu items
  private JRadioButtonMenuItem lineItem,  rectangleItem, circleItem,  // Types
                               curveItem, textItem;
  private JCheckBoxMenuItem    redItem,   yellowItem,                 // Colors
                               greenItem, blueItem ;  

If you recompile Sketcher once more, you can run the application again to try out the menus. If you extend the File menu, you will see that it has the menu items that we have added.

Now if you extend the Elements menu it should appear as shown with the Line and Blue items checked.

How It Works

We have defined the variables storing references to the menu items for the drop-down menus as private members of the class. For the File menu items they are of type JMenuItem. In the Element menu the items select a type of shape to be drawn, and, as these are clearly mutually exclusive, we are using type JRadioButtonMenuItem for them. We could use the same type for the element color items, but in order to try it out we are using the JCheckBoxMenuItem type.

To create the items in the File menu, we pass the String for the label for each to the add() method and leave it to the JMenu object to create the JMenuItem object.

The first group of Elements menu items are JRadioButtonMenuItem objects and we create each of these in the argument to the add()method. To ensure only one is checked at a time, we also add them to a ButtonGroup object. The color menu items are of type JCheckBoxMenuItem so the current selection is indicated by a check mark on the menu. We will make Line the default element type and Blue the default color, so we set both of these as checked by specifying true as the second argument to the constructor.

The other items will be unchecked initially because we have specified the second argument as false. We could have omitted the second argument to leave these items unchecked by default. It then means that you need to remember the default in order to determine what is happening. It is much better to set the checks explicitly.

You can see the effect of the addSeparator() method from the JMenu class. It produces the horizontal bar separating the items for element type from those for color. If you select any of the unchecked element type items on the Elements pull-down menu, they will be checked automatically, and only one can appear checked. More than one of the color items can be checked at the moment, but we will add some code in the next chapter to make sure only one of these items is checked at any given time.

We could try putting the color selection item in an additional pull-down menu. We could do this by changing the code that follows the statement adding the separator in the Elements menu as follows:


    JMenu colorMenu = new JMenu("Color");         // Color submenu
    elementMenu.add(colorMenu);                   // Add the submenu
    colorMenu.add(redItem = new JCheckBoxMenuItem("Red", false));
    colorMenu.add(yellowItem = new JCheckBoxMenuItem("Yellow", false));
    colorMenu.add(greenItem = new JCheckBoxMenuItem("Green", false));
    colorMenu.add(blueItem = new JCheckBoxMenuItem("Blue", true));

Now we add a JMenu object, colorMenu, to the pull-down menu for Elements. This has its own pull-down menu consisting of the color menu items. The Color item will be displayed on the Elements menu with an arrow to show a further pull-down menu is associated with it. If you run the application again and extend the pull-down menus, the window should be as shown.

Whether you choose this menu structure or the previous one is a matter of taste. It might even be better to have a separate item on the menu bar but we'll leave it at that for now. We will see in the next chapter that the programming necessary to deal with menu selections by the user is the same in either case.

Adding an Shortcut for a Menu Item

A shortcut is a unique key combination used to select a menu on the menu bar direct from the keyboard. A typical shortcut under Windows would be the Alt key plus a letter from the menu item label, so the shortcut for the File menu item might be Alt+F. When you enter this key combination the menu is displayed. We can add shortcuts for the File and Elements menu items by adding the following statements after we add the menu items to the menu bar:

    fileMenu.setMnemonic('F');                    // Create shortcut
    elementMenu.setMnemonic('E');                 // Create shortcut

The setMnemonic()method is inherited from the AbstractButton class, so all subclasses of this class inherit this method. The argument is a character in the String that is the label for the item that is to be the shortcut character – under Windows the File menu would then pop up if you key Alt+F. The effect of setMnemonic() is to implement the shortcut and underline the shortcut character letter in the menu label.

An accelerator is a key combination that you can enter to select an item from a menu. Under Windows, the Ctrl key is frequently used in combination with a letter as an accelerator for a menu item, so Ctrl+L might be the combination for the Line item in the Elements menu. For menu items you call the setAccelerator() method to define an accelerator. For example, for the Line menu item you could write:

lineItem.setAccelerator(KeyStroke.getKeyStroke('L', Event.CTRL_MASK )); 

The KeyStroke class defines a keystroke combination. The static method, getKeyStroke() returns the KeyStroke object corresponding to the arguments. The first argument is the character and the second argument specifies the modifier key. The Event class (in java.awt) defines Event.SHIFT_MASK, Event.ALT_MASK, and what we used here, Event.CTRL_MASK. If you want to combine the Alt and Ctrl keys for instance, you can add them – Event.ALT_MASK + Event.CTRL_MASK.

Let's see how this works in practice.

Try It Out – Adding Menu Shortcuts

We can add some shortcuts to Sketcher by amending the statements that add the items to the File menu in the SketchFrame class constructor:

// Frame for the Sketcher application
import javax.swing.*;
import java.awt.Event;

public class SketchFrame extends JFrame {
  // Constructor
  public SketchFrame(String title) {
    setTitle(title);                              // Call the base constructor
    setJMenuBar(menuBar);                        // Add the menu bar to the window

    JMenu fileMenu = new JMenu("File");          // Create File menu
    JMenu elementMenu = new JMenu("Elements");   // Create Elements menu
    fileMenu.setMnemonic('F');                   // Create shortcut
    elementMenu.setMnemonic('E');                // Create shortcut

    // Construct the file pull down menu as before...

    // Add File menu accelerators
    newItem.setAccelerator(KeyStroke.getKeyStroke('N',Event.CTRL_MASK ));
    openItem.setAccelerator(KeyStroke.getKeyStroke('O',Event.CTRL_MASK ));
    saveItem.setAccelerator(KeyStroke.getKeyStroke('S',Event.CTRL_MASK ));
    printItem.setAccelerator(KeyStroke.getKeyStroke('P',Event.CTRL_MASK ));

    // Construct the Element pull down menu as before...

    // Add element type accelerators
    lineItem.setAccelerator(KeyStroke.getKeyStroke('L',Event.CTRL_MASK ));
    rectangleItem.setAccelerator(KeyStroke.getKeyStroke('E',Event.CTRL_MASK ));
    circleItem.setAccelerator(KeyStroke.getKeyStroke('I',Event.CTRL_MASK ));
    curveItem.setAccelerator(KeyStroke.getKeyStroke('V',Event.CTRL_MASK ));


    // Create the color submenu as before...

    // Add element color accelerators
    redItem.setAccelerator(KeyStroke.getKeyStroke('R',Event.CTRL_MASK ));
    yellowItem.setAccelerator(KeyStroke.getKeyStroke('Y',Event.CTRL_MASK ));
    greenItem.setAccelerator(KeyStroke.getKeyStroke('G',Event.CTRL_MASK ));
    blueItem.setAccelerator(KeyStroke.getKeyStroke('B',Event.CTRL_MASK ));

    menuBar.add(fileMenu);                        // Add the file menu
    menuBar.add(elementMenu);                     // Add the element menu

  // File menu items and the rest of the class as before...

If you save after you have made the changes, you can recompile Sketcher and run it again. The file menu will now appear as show below:

How It Works

We use the setMnemonic() method to set the shortcuts for the menu bar items and the setAccelerator() method to add accelerators to the submenu items. You must make sure that you do not use duplicate key combinations, and the more menu items you have accelerators for, the trickier this gets. The File menu here defines the standard Windows accelerators. You can see that the setAccelerator() method adds the shortcut key combination to the item label.

The menus don't actually work at the moment but at least they look good! We will start adding the code to implement menu operations in the next chapter.

Previous Next
JavaScript Editor Java Tutorials Free JavaScript Editor