Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6566185

JMenu is unable to display popup menu after popup is shown by another component

    XMLWordPrintable

    Details

      Description

      FULL PRODUCT VERSION :
      java version "1.6.0_01"
      Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
      Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      Linux 2.6.8-2-686 #1 Tue Aug 16 13:22:48 UTC 2005 i686 GNU/Linux
      Windows XP SP2

      A DESCRIPTION OF THE PROBLEM :
      When the JPopupMenu belonging to a JMenu is displayed in another component as a context menu (in response to a right-click, for example) using JPopupMenu.show(Component invoker, int x, int y), the JMenu can no longer display the popup menu.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create a simple Swing application with a menu bar and a JLabel.

      The menu bar contains a single JMenu with one or two JMenuItems.

      Add a mouse listener to the JLabel, which displays the JPopupMenu obtained from the JMenu with getPopupMenu.

      When the application is run, the JMenu at first works normally: it displays the popup menu when it is clicked.

      Now use right-click in the JPanel to display the popup menu in the JPanel. This also works normally.

      But now, when you click the JMenu in the menu bar, it no longer displays the popup menu.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I expect that the JMenu should still be able to display the popup menu, after it has been displayed in the JPanel.

      That is to say, I expect that the JMenu and the JPanel should be able to share the popup menu. The documentation does not state that this is not allowed.
      ACTUAL -
      After the popup menu has been displayed in the JPanel, the JMenu can no longer display it.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      (NO ERROR MESSAGES)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.awt.BorderLayout;

      public class PopupProblem {
      protected JMenu menu;
      protected final JPopupMenu popupMenu;

      public PopupProblem() {
      menu = new JMenu("File");

      menu.add(new JMenuItem("Open"));
      menu.add(new JMenuItem("Save"));
      menu.add(new JMenuItem("Save as..."));
      menu.addSeparator();
      menu.add(new JMenuItem("Exit"));

      popupMenu = menu.getPopupMenu();

      createAndShowUI();
      }

      protected void createAndShowUI() {
      JFrame frame = new JFrame("PopupProblem");

      JMenuBar menubar = new JMenuBar();

      menubar.add(menu);

      frame.setJMenuBar(menubar);

      JPanel panel = new JPanel(new BorderLayout());

      JLabel label = new JLabel("This label has a popup menu",
      SwingConstants.CENTER);

      label.setOpaque(true);
      label.setBackground(Color.yellow);

      label.addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent e) {
      handleMouseEvent(e);
      }

      public void mousePressed(MouseEvent e) {
      handleMouseEvent(e);
      }

      public void mouseReleased(MouseEvent e) {
      handleMouseEvent(e);
      }
      });

      panel.add(label, BorderLayout.CENTER);

      frame.getContentPane().add(panel);

      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(400, 500);
      frame.setVisible(true);
      }


      protected void handleMouseEvent(MouseEvent e) {
      if (e.isPopupTrigger()) {
      displayPopupMenu(e);
      }
      }

      protected void displayPopupMenu(MouseEvent e) {
      popupMenu.show(e.getComponent(), e.getX(), e.getY());
      }


      public static void main(String[] args) {
      PopupProblem pp = new PopupProblem();
      }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Re-set the invoker of the popup menu explicitly each time the popup becomes invisible, using a popup menu listener. Add this code to the constructor in the test case, immediately after the call to menu.getPopupMenu:

      popupMenu.addPopupMenuListener(new PopupMenuListener() {
      public void popupMenuCanceled(PopupMenuEvent e) {
      }

      public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
      popupMenu.setInvoker(menu);
      }

      public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
      }
      });

        Attachments

          Activity

            People

            Assignee:
            Unassigned Unassigned
            Reporter:
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Dates

              Created:
              Updated:
              Imported:
              Indexed: