The PopupMenu Class

One of Swing’s nifty components is JPopupMenu, a menu that automatically appears when you press the appropriate mouse button inside of a component. (On a Windows system, for example, clicking the right mouse button invokes a popup menu.) Which button you press depends on the platform you’re using; fortunately, you don’t have to care—Swing figures it out for you.

The care and feeding of JPopupMenu is basically the same as any other menu. You use a different constructor (JPopupMenu( )) to create it, but otherwise, you build a menu and add elements to it the same way. The big difference is you don’t need to attach it to a JMenuBar. Instead, just pop up the menu whenever you need it.

The following example, PopupColorMenu, contains three buttons. You can use a JPopupMenu to set the color of each button or the frame itself, depending on where you press the mouse. Figure 14.5 shows the example in action; the user is preparing to change the color of the bottom button.

The PopupColorMenu application

Figure 14-5. The PopupColorMenu application

//file: PopUpColorMenu.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class PopUpColorMenu extends JFrame 
                            implements ActionListener {
  JPopupMenu colorMenu;
  Component selectedComponent;
  
  public PopUpColorMenu( ) {
    super("PopUpColorMenu v1.0");
    setSize(100, 200);
    setLocation(200, 200);
    addWindowListener(new WindowAdapter( ) {
      public void windowClosing(WindowEvent e) { System.exit(0); }
    });
    
    MouseListener mouseListener = new MouseAdapter( ) {
      public void mousePressed(MouseEvent e) { checkPopup(e); }
      public void mouseClicked(MouseEvent e) { checkPopup(e); }
      public void mouseReleased(MouseEvent e) { checkPopup(e); }
      private void checkPopup(MouseEvent e) {
        if (e.isPopupTrigger( )) {
          selectedComponent = e.getComponent( );
          colorMenu.show(e.getComponent(), e.getX(), e.getY( ));
        }
      }
    };

    final Container content = getContentPane( );
    content.setLayout(new FlowLayout( ));
    JButton button = new JButton("Uno");
    button.addMouseListener(mouseListener);
    content.add(button);
    button = new JButton("Due");
    button.addMouseListener(mouseListener);
    content.add(button);
    button = new JButton("Tre");
    button.addMouseListener(mouseListener);
    content.add(button);
    
    colorMenu = new JPopupMenu("Color");
    colorMenu.add(makeMenuItem("Red"));
    colorMenu.add(makeMenuItem("Green"));
    colorMenu.add(makeMenuItem("Blue"));
    
    getContentPane( ).addMouseListener(mouseListener);

    setVisible(true);
  }
  
  public void actionPerformed(ActionEvent e) {
    String color = e.getActionCommand( );
    if (color.equals("Red"))
      selectedComponent.setBackground(Color.red);
    else if (color.equals("Green"))
      selectedComponent.setBackground(Color.green);
    else if (color.equals("Blue"))
      selectedComponent.setBackground(Color.blue);
  }
  
  private JMenuItem makeMenuItem(String label) {
    JMenuItem item = new JMenuItem(label);
    item.addActionListener( this );
    return item;
  }

  public static void main(String[] args) {
    new PopUpColorMenu( );
  }
}

Because the popup menu is triggered by mouse events, we need to register a MouseListener for any of the components to which it applies. In this example, all three buttons and the content pane of the frame are eligible for the color popup menu. Therefore, we add a mouse event listener for all of these components explicitly. The same instance of an anonymous inner MouseAdapter subclass is used in each case. In this class, we override the mousePressed( ) , mouse-Released( ), and mouseClicked( ) methods to display the popup menu when we get an appropriate event. How do we know what an “appropriate event” is? Fortunately, we don’t need to worry about the specifics of our user’s platform; we just need to call the event’s isPopupTrigger( ) method. If this method returns true, we know the user has done whatever normally displays a popup menu on his or her system.

Once we know that the user wants to raise a popup menu, we display the popup menu by calling its show( ) method with the mouse event coordinates as arguments.

If we wanted to provide different menus for different types of components or the background, we’d create different mouse listeners for each different kind of component. The mouse listeners would invoke different kinds of popup menus as appropriate.

The only thing left is to handle the action events from the popup menu items. We use a helper method called makeMenuItem( ) to register the PopUpColorMenu window as an action listener for every item we add. The example implements ActionListener and has the required actionPerformed( ) method. This method reads the action command from the event, which is equal to the selected menu item’s label by default. It then sets the background color of the selected component appropriately.

Get Learning Java now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.