6949414: JMenu.buildMenuElementArray() endless loop
authoralexsch
Tue, 05 Apr 2016 21:13:44 +0400
changeset 37561 dcb7441b014d
parent 37560 5070d74da2bc
child 37562 5b36d70170d6
6949414: JMenu.buildMenuElementArray() endless loop 6424606: behavior of returned from MenuSelectionManager.defaultManager() object is inconsistent with spec Reviewed-by: serb, ssadetsky
jdk/src/java.desktop/share/classes/javax/swing/JMenu.java
jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java
jdk/test/javax/swing/JPopupMenu/6949414/JPopupMenuEndlessLoopTest.java
--- a/jdk/src/java.desktop/share/classes/javax/swing/JMenu.java	Tue Apr 05 09:17:15 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JMenu.java	Tue Apr 05 21:13:44 2016 +0400
@@ -1296,7 +1296,7 @@
      * @return the array of menu items
      */
     private MenuElement[] buildMenuElementArray(JMenu leaf) {
-        Vector<MenuElement> elements = new Vector<MenuElement>();
+        Vector<MenuElement> elements = new Vector<>();
         Component current = leaf.getPopupMenu();
         JPopupMenu pop;
         JMenu menu;
@@ -1314,11 +1314,14 @@
             } else if (current instanceof JMenuBar) {
                 bar = (JMenuBar) current;
                 elements.insertElementAt(bar, 0);
-                MenuElement me[] = new MenuElement[elements.size()];
-                elements.copyInto(me);
-                return me;
+                break;
+            } else {
+                break;
             }
         }
+        MenuElement me[] = new MenuElement[elements.size()];
+        elements.copyInto(me);
+        return me;
     }
 
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java	Tue Apr 05 09:17:15 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java	Tue Apr 05 21:13:44 2016 +0400
@@ -797,9 +797,11 @@
             if (invoker instanceof JPopupMenu) {
                 invoker = ((JPopupMenu)invoker).getInvoker();
             }
-            grabbedWindow = invoker instanceof Window?
-                    (Window)invoker :
-                    SwingUtilities.getWindowAncestor(invoker);
+            grabbedWindow = (invoker == null)
+                    ? null
+                    : ((invoker instanceof Window)
+                            ? (Window) invoker
+                            : SwingUtilities.getWindowAncestor(invoker));
             if(grabbedWindow != null) {
                 if(tk instanceof sun.awt.SunToolkit) {
                     ((sun.awt.SunToolkit)tk).grab(grabbedWindow);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JPopupMenu/6949414/JPopupMenuEndlessLoopTest.java	Tue Apr 05 21:13:44 2016 +0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.MenuElement;
+import javax.swing.MenuSelectionManager;
+import javax.swing.SwingUtilities;
+
+/**
+ * @test
+ * @bug 6949414 6424606
+ * @summary JMenu.buildMenuElementArray() endless loop
+ * @run main/timeout=5 JPopupMenuEndlessLoopTest
+ */
+public class JPopupMenuEndlessLoopTest {
+
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+
+            JPopupMenu popup = new JPopupMenu("Popup Menu");
+            JMenu menu = new JMenu("Menu");
+            menu.add(new JMenuItem("Menu Item"));
+            popup.add(menu);
+            menu.doClick();
+            MenuElement[] elems = MenuSelectionManager
+                    .defaultManager().getSelectedPath();
+
+            if (elems == null || elems.length == 0) {
+                throw new RuntimeException("Empty Selection");
+            }
+
+            if (elems[0] != popup || elems[1] != menu) {
+                throw new RuntimeException("Necessary menus are not selected!");
+            }
+        });
+    }
+}