Question

I have an application with a popup menu. I'd like to use the popup in the usual way (i.e., it should appear when the user right-clicks anywhere in the window), but I'd also like to attach it to the main MenuBar at the top of the window. I'm not sure how to do this.

I'd thought it would as simple as calling myJMenuBar.add(myPopupMenu) but this doesn't work.

JMenuBar.add() wants a JMenu parameter, not a JPopupMenu.

Does anyone have any suggestions?

Was it helpful?

Solution

Instead of trying to reuse the JPopupMenu object, the best approach would be to encapsulate the actions that the menus perform, and reuse those. The popup would trigger those actions, as would the menu items.

From the Action JavaDoc:

In addition to the actionPerformed method defined by the ActionListener interface, this interface allows the application to define, in a single place:

  • One or more text strings that describe the function. These strings can be used, for example, to display the flyover text for a button or to set the text in a menu item.
  • One or more icons that depict the function. These icons can be used for the images in a menu control, or for composite entries in a more sophisticated user interface.
  • The enabled/disabled state of the functionality. Instead of having to separately disable the menu item and the toolbar button, the application can disable the function that implements this interface. All components which are registered as listeners for the state change then know to disable event generation for that item and to modify the display accordingly.

and

JPopupMenu, JToolBar and JMenu all provide convenience methods for creating a component and setting the Action on the corresponding component. Refer to each of these classes for more information.

OTHER TIPS

I had the same issue. A right-mouse-click as well as a top menu with exactly the same (complicated) set of menu items. The 'Action' class is something to consider if you are talking about enablement choices, but it's not dealing with visibility and in my case there was also a dynamic list of entries based on a current selection that I wanted to reuse.

So I ended up implementing a 'Bridge' design pattern (I think) for the methods I actually use (add() and addSeparator()):

  public static class MenuBridge
  {
    private JPopupMenu popupMenu;
    private JMenu menu;

    public MenuBridge(JPopupMenu popupMenu)
    {
      this.popupMenu = popupMenu;
    }

    public MenuBridge(JMenu menu)
    {
      this.menu = menu;
    }

    public void addSeparator()
    {
      if(popupMenu!=null) popupMenu.addSeparator();
      else menu.addSeparator();
    }

    public void add(JMenuItem item)
    {
      if(popupMenu!=null) popupMenu.add(item);
      else menu.add(item);
    }
  }

So then I can write a reusable method that computes the menu items and synchronize my right mouse click with the top-level menu:

public void addTaskMenuItems(DefaultMenu menu, List<MDProcTask> taskList)
{
  ...
  menu.add()/menu.addSeparator()
  ...
}

addTaskMenuItems(new DefaultMenu(popupMenu),taskList);
...
taskMenu.addMenuListener( new MenuListener() {
      public void menuCanceled(MenuEvent menuevent)
      {
      }
      public void menuDeselected(MenuEvent menuevent)
      {
      }
      public void menuSelected(MenuEvent menuevent)
      {
        taskMenu.removeAll();
        addTaskMenuItems( new DefaultMenu(taskMenu),getSelectedTasks());
        taskMenu.revalidate();
      }});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top