Previous | Next | Trail Map | Creating a User Interface | Using Components, the GUI Building Blocks

How to Use Menus

The following applet shows many of the menu features you're likely to use. The window it brings up has a menu bar that contains five menus. Each menu contains one or more items. Menu 1 is a tear-off menu; by clicking the dashed line, the user creates a new window that contains the same menu items as Menu 1. (Currently, tear-off menus are implemented only on the Solaris platform, not in Windows 95/NT or MacOS.) Menu 2's only item has a checkbox. Menu 3 contains a separator between its second and third items. Menu 4 contains a submenu. Menu 5 is the window's help menu, which (depending on the platform) generally means that it's set off to the right. When the user clicks on any menu item, the window displays a string indicating which item was clicked and what menu it's in.


Your browser doesn't understand the <APPLET> tag. Here's a snapshot of the window the button brings up:

When you press Menu 1, you can see a tear-off indicator:

Here's what the torn off menu looks like:

Menu 2 has an item with a checkbox:

Menu 3 has a separator:

Menu 4 has a submenu:



Note: Because some old browsers don't support 1.1, the above applet is a 1.0 version (here is the 1.0 code; here's the 1.1 code). To run the 1.1 version of the applet, go to example-1dot1/MenuWindow.html.

The reason the applet brings up a window to demonstrate menus is that the AWT limits where you can use menus. Menus can exist only in menu bars, and menu bars can be attached only to windows (specifically, to Frames).


Note: Popup menus, introduced in JDK 1.1, can appear in any window.

If menus aren't appropriate or possible in your program, you should look into other ways of presenting the user with options: checkboxes, choices, and lists.

Menu functionality in the AWT is provided by several classes. These classes do not inherit from Component, since many platforms place severe limits on menu capabilities. Instead, menu classes inherit from the MenuComponent(in the API reference documentation) class. The AWT provides the following MenuComponent subclasses to support menus:

MenuItem(in the API reference documentation)
Each item in a menu is represented by a MenuItem object.
CheckboxMenuItem(in the API reference documentation)
Each menu item that contains a checkbox is represented by a CheckboxMenuItem object. CheckboxMenuItem is a subclass of MenuItem.
Menu(in the API reference documentation)
Each menu is represented by a Menu object. Menu is implemented as a subclass of MenuItem so that you can easily create a submenu by adding one menu to another.
MenuBar(in the API reference documentation)
Menu bars are implemented by the MenuBar class. A MenuBar represents the platform-dependent notion of a group of menus attached to a window. MenuBars can not be bound to Panels.

To be able to contain a MenuComponent, an object must adhere to the MenuContainer(in the API reference documentation) interface. The Frame, Menu, and MenuBar classes are the only AWT classes that currently implement MenuContainer.

Here's the code for the window that the above applet brings up. This code can be run as a standalone application or, with the help of the AppletButton class, as an applet. Here's just the code that deals with menus:

public class MenuWindow extends Frame {
    . . .
    public MenuWindow() {
        MenuBar mb;
        Menu m1, m2, m3, m4, m4_1, m5;
        MenuItem mi1_1, mi1_2, mi3_1, mi3_2, mi3_3, mi3_4,
                 mi4_1_1, mi5_1, mi5_2;
        CheckboxMenuItem mi2_1;

        ...//Add the output displayer to this window...

        //Build the menu bar.
        mb = new MenuBar();
        setMenuBar(mb);
    
        //Build first menu in the menu bar.
	//Specifying the second argument as true
	//makes this a tear-off menu.
        m1 = new Menu("Menu 1", true);
        mb.add(m1);
        mi1_1 = new MenuItem("Menu Item 1_1");
        m1.add(mi1_1);
        mi1_2 = new MenuItem("Menu Item 1_2");
        m1.add(mi1_2);

        //Build help menu.
        m5 = new Menu("Menu 5");
        mb.add(m5); //just setting the help menu doesn't work; must add it
        mb.setHelpMenu(m5);
        mi5_1 = new MenuItem("Menu Item 5_1");
        m5.add(mi5_1);
        mi5_2 = new MenuItem("Menu Item 5_2");
        m5.add(mi5_2);

        //Build second menu in the menu bar.
        m2 = new Menu("Menu 2");
        mb.add(m2);
        mi2_1 = new CheckboxMenuItem("Menu Item 2_1");
        m2.add(mi2_1);
    
        //Build third menu in the menu bar.
        m3 = new Menu("Menu 3");
        mb.add(m3);
        mi3_1 = new MenuItem("Menu Item 3_1");
        m3.add(mi3_1);
        mi3_2 = new MenuItem("Menu Item 3_2");
        m3.add(mi3_2);
        m3.addSeparator();
        mi3_3 = new MenuItem("Menu Item 3_3");
        m3.add(mi3_3);
        mi3_4 = new MenuItem("Menu Item 3_4");
        mi3_4.disable();
        m3.add(mi3_4);

        //Build fourth menu in the menu bar.
        m4 = new Menu("Menu 4");
        mb.add(m4);
        m4_1 = new Menu("Submenu 4_1");
        m4.add(m4_1);
        mi4_1_1 = new MenuItem("Menu Item 4_1_1");
        m4_1.add(mi4_1_1);
    }
    . . .
    public boolean action(Event event, Object arg) {
        String str = "Action detected";

        if (event.target instanceof MenuItem) {
            MenuItem mi=(MenuItem)(event.target);
            str += " on " + arg;
            if (mi instanceof CheckboxMenuItem) {
                    str += " (state is " 
                           + ((CheckboxMenuItem)mi).getState()
                           + ")";
            }
            MenuContainer parent = mi.getParent();
            if (parent instanceof Menu) {
                str += " in " + ((Menu)parent).getLabel();
            } else {
                str += " in a container that isn't a Menu";
            }
        }
        str += ".\n";
        ...//Display the string in the output area...
        return false;
    }


Previous | Next | Trail Map | Creating a User Interface | Using Components, the GUI Building Blocks