Richard G Baldwin (512) 223-4758, baldwin@austin.cc.tx.us, http://www2.austin.cc.tx.us/baldwin/

The AWT Package, Popup Menus

Java Programming, Lecture Notes # 144, Revised 01/27/98.

Preface

Students in Prof. Baldwin's Advanced Java Programming classes at ACC are responsible for knowing and understanding all of the material in this lesson.

Introduction

This series of lessons is concentrating on package java.awt where most of the functionality exists for providing the user interface to your application or applet.

We have learned how to handle events and how to use layout managers.These two topics form the basis for the design and implementation of a Graphical User Interface.

Now we are learning about the various components that we can combine with layout and event handling to produce an effective Graphical User Interface.

The available components are defined by classes in the package java.awt. Our approach is to group those classes into categories and study the material on a category basis. As of this writing, it looks as if the remaining categories are:

As things develop, it may be necessary to modify these groupings.

Menus

The inheritance hierarchy for menus is as shown below.
 
java.lang.Object
        |
        +----MenuShortcut 
        |
        +----java.awt.MenuComponent 
                |
                +----java.awt.MenuBar
                |
                +----java.awt.MenuItem 
                        |
                        +----java.awt.Menu
                        |
                        +----java.awt.CheckboxMenuItem
                        |
                        +----java.awt.PopupMenu
There are a number of interesting issues associated with menus which are being discussed in this series of documents.

Previous lessons discussed and provided sample programs for the following classes.

This lesson will discuss and and provide a sample program for Sample programs in a previous lessons made use of all the menu-related classes except PopupMenu. We will provide a sample program which produces a popup menu in place of an ordinary pulldown menu.

The sample program in this lesson will be very similar to the sample program in the lesson on the CheckboxMenuItem class. However, this lesson will substitute a PopupMenu object in place of the combination of Menu and MenuBar objects in that program.

PopupMenu Class

This class is used to instantiate objects which behave as popup menus. Once the menu appears on the screen, the processing of the items on the menu is the same as processing items on the pulldown menus studied in earlier lessons.

This class has no fields and the following public constructors:

The detailed description of the second version of the constructor extracted from the JDK 1.1.3 documentation follows:
 
 public PopupMenu(String label)

    Creates a new popup menu with the specified name. 

    Parameters: 
        title - the title string for the popup menu 
This suggests that there is a title somewhere on the menu that is derived from the String object passed as a parameter.

In the sample program that follows, we will instantiate a PopupMenu object using the second form of the constructor using JDK 1.1.3. However, when tested under Win95, the title specified by the String object passed as a parameter to the constructor doesn't actually appear anywhere on the menu. This may be a bug or may be a misunderstanding on the part of this author as to the purpose of the String parameter..

This class provides two methods. In this lesson we are only interested in one of those methods: show(). We will use the show() method to display the menu.

The long description of the show() method from the JDK 1.1 documentation follows:
 
 public void show(Component origin,
                  int x,
                  int y)

    Shows the popup menu at the x, y position relative
    to an origin component. The origin component 
    must be contained within the component hierarchy
    of the popup menu's parent. Both the origin and the
    parent must be showing on the screen for this method
    to be valid. 

    Parameters: 
        origin - the component which defines the
                 coordinate space 
        x - the x coordinate position to popup the menu 
        y - the y coordinate position to popup the menu 
.

Sample Program

This program is designed to be compiled and run under JDK 1.1. It illustrates the use of PopupMenu objects composed of CheckboxMenuItem objects.

This application places one PopupMenu object in a Frame object. The menu contains three items of type CheckboxMenuItem.

The PopupMenu appears whenever the user clicks inside the Frame object and below the banner portion across the top of the Frame object. When it appears, the upper left-hand corner of the PopupMenu is located near the position of the mouse click.

According to the documentation for JDK 1.1.3, the overloaded constructor used in the program should produce a popup menu with the name "Popup Menu." However, when the menu appears on the screen, there is no name attached.

Selection of an item in the PopupMenu object generates an ItemEvent that is trapped using an ItemListener object which overrides the itemStateChanged() method. Information about the menu item that was selected is displayed on the screen.

An earlier lesson contained a detailed discussion of the use of CheckboxMenuItem objects, and they are only incidental to this lesson which is designed to illustrate the use of PopupMenu objects. Therefore, they won't be discussed further here.

A windowClosing() event listener object is instantiated and registered on the frame to terminate the program when the frame is closed.

The program was tested using JDK 1.1 running under Win95.

Interesting Code Fragments

This program is very similar to the program in a previous lesson which discussed the use of CheckboxMenuItem objects in an ordinary pull-down menu. Therefore, in this section we will discuss only those code fragments which have become interesting due to the use of the PopupMenu object.

The first interesting code fragment is the code that instantiates a PopupMenu object and adds three previously instantiated CheckboxMenuItem objects to it.

As mentioned earlier, the constructor that is being invoked here should cause the popup menu to have the name "Popup Menu". However, when compiled and run using the version of JDK 1.1.3 available for Win95, the name does not appear on the menu. Rather, the menu simply looks like a three-dimensional grey panel with highlighting on the left side and the top. The only text appearing on the panel is the three menu items.
 
    PopupMenu myPopupMenu = new PopupMenu("Popup Menu");
    myPopupMenu.add(firstMenuItem);
    myPopupMenu.add(secondMenuItem);
    myPopupMenu.add(thirdMenuItem); 
The next code fragment is interesting because of the way that it differs from previous code involving menus. In previous programs, the procedure was to add one or more Menu objects to an object of type MenuBar, and then to associate the MenuBar object with the frame by invoking the method setMenuBar().

However, to associate a PopupMenu object with a Frame object, we simply use the typical object.add() method that we would use to associate most other components with a container.
 
Frame myFrame = new Frame("Copyright 1997, R.G.Baldwin");
myFrame.addMouseListener(
                new MouseProcessor(myFrame,myPopupMenu));
myFrame.add(myPopupMenu);
The next interesting code fragment is the overridden mousePressed() method of the MouseListener interface which is here encapsulated in a class named MouseProcessor.

The purpose of this class is to instantiate a listener object that will trap MousePressed events on the Frame object and show() the PopupMenu object at the location of the mouse event.

This is a typical MouseListener class and the only thing new is the use of the show() method of the PopupMenu class mentioned earlier.

Note that a reference to the PopupMenu object and a reference to the Frame object are passed in when the object is instantiated. They are saved with the local names of aPopupMenu and aFrame. Both of these references are needed for invocation of the show() method in the following code fragment. The reference to the Frame object is used to establish the location of the menu when it appears. The reference to the PopupMenu object simply specifies which menu to show.
 
  public void mousePressed(MouseEvent e){
    aPopupMenu.show(aFrame,e.getX(),e.getY());
  }//end mousePressed()

Program Listing

This section contains a complete listing of the program. See the previous sections for an operational description of the program.
 
/*File Menu04.java Copyright 1997, R.G.Baldwin
This program is designed to be compiled and run under 
JDK 1.1

Illustrates use of PopupMenu objects composed of 
CheckboxMenuItems.

This application places one PopupMenu in a Frame object.
The menu contains three items of type CheckboxMenuItem.
The PopupMenu appears whenever the user clicks inside the
Frame object and below the banner portion across the top 
of the Frame object.  The PopupMenu object is located 
near position of the mouse click.

Selection of an item in the PopupMenu generates an 
ItemEvent that is trapped using a Listener object of type
ItemListener which overrides the itemStateChanged()
method.  Information about the menu item that was selected
is displayed on the screen.

An earlier lesson contained a detailed discussion of the
use of CheckboxMenuItem objects, and they are only 
incidental to this lesson which is designed to illustrate
the use of PopupMenu objects.

A windowClosing() event listener object is instantiated
and registered on the frame to terminate the program when
the frame is closed.

The program was tested using JDK 1.1.3 running under Win95.
**********************************************************/

import java.awt.*;
import java.awt.event.*;
//=======================================================//

public class Menu04 {
  public static void main(String[] args){
    GUI gui = new GUI();//instantiate a GUI
  }//end main
}//end class Menu04
//=======================================================//

class GUI {
  public GUI(){//constructor
    //Instantiate CheckboxMenuItem objects  
    CheckboxMenuItem firstMenuItem = 
                        new CheckboxMenuItem("First Item");
    CheckboxMenuItem secondMenuItem = 
                       new CheckboxMenuItem("Second Item");
    CheckboxMenuItem thirdMenuItem = 
                        new CheckboxMenuItem("Third Item");
     
    //Instantiate an ItemListener object and register it 
    // on the CheckboxMenuItem objects.
    CheckBoxMenuProcessor eventProcessor = 
                               new CheckBoxMenuProcessor();
    firstMenuItem.addItemListener(eventProcessor);
    secondMenuItem.addItemListener(eventProcessor);
    thirdMenuItem.addItemListener(eventProcessor);
    
    //Instantiate a PopupMenu object and add the 
    // CheckboxMenuItem objects to it
    PopupMenu myPopupMenu = new PopupMenu("Popup Menu");
    myPopupMenu.add(firstMenuItem);
    myPopupMenu.add(secondMenuItem);
    myPopupMenu.add(thirdMenuItem);    
    
    Frame myFrame = new Frame(
                            "Copyright 1997, R.G.Baldwin");
    myFrame.addMouseListener(
                  new MouseProcessor(myFrame,myPopupMenu));
    //This is different from menus with MenuBar object.
    // Note that it uses an ordinary add() method.
    myFrame.add(myPopupMenu);
    myFrame.setSize(250,100);
    myFrame.setVisible(true);

    //Instantiate and register a window listener to 
    // terminate the program when the Frame is closed. 
    myFrame.addWindowListener(new Terminate());
  }//end constructor
}//end class GUI definition
//=======================================================//

//Class to trap a mousePressed event and display the 
// PopupMenu object at the location of the mouse event.
class MouseProcessor extends MouseAdapter{
  Frame aFrame;
  PopupMenu aPopupMenu;
  
  //constructor
  MouseProcessor(Frame inFrame, PopupMenu inPopupMenu){
    aFrame = inFrame;
    aPopupMenu = inPopupMenu;
  }//end constructor

  public void mousePressed(MouseEvent e){
    //Display the PopupMenu on the specified Frame near the
    // specified coordinate position of the mouse click,
    // provided that the coordinates of the click are not
    // in the banner at the top.
    aPopupMenu.show(aFrame,e.getX(),e.getY());
  }//end mousePressed()
}//end class MouseProcessor
//=======================================================//

//Class to instantiate an ItemListener object to be 
// registered on the menu items.
class CheckBoxMenuProcessor implements ItemListener{
  public void itemStateChanged(ItemEvent e){
    //Display the menu item that generated the ItemEvent
    System.out.println(e.getSource());
  }//end itemStateChanged
}//end class CheckBoxMenuProcessor
//=======================================================//

class Terminate extends WindowAdapter{
  public void windowClosing(WindowEvent e){
    System.exit(0);//terminate the program
  }//end windowClosing
}//end class Terminate
//=======================================================//
-end-