7042497: javax.swing.JOptionPane.showInternalConfirmDialog throws RuntimeException
authorpsadhukhan
Mon, 22 May 2017 11:21:49 +0530
changeset 47128 f88316f78414
parent 47127 56441eb0a8ec
child 47129 9db10256ba85
7042497: javax.swing.JOptionPane.showInternalConfirmDialog throws RuntimeException Reviewed-by: ssadetsky, aniyogi
jdk/src/java.desktop/share/classes/javax/swing/JOptionPane.java
jdk/test/javax/swing/JOptionPane/7042497/JOptionPaneConfirmDlgTest.java
--- a/jdk/src/java.desktop/share/classes/javax/swing/JOptionPane.java	Fri May 19 07:25:48 2017 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JOptionPane.java	Mon May 22 11:21:49 2017 +0530
@@ -1228,6 +1228,16 @@
                                         messageType, icon, null, null);
     }
 
+    private static boolean checkFrameForComponent(Component parentComponent) {
+        if (parentComponent == null) {
+            return false;
+        }
+        if (parentComponent instanceof Frame) {
+            return true;
+        }
+        return checkFrameForComponent(parentComponent.getParent());
+    }
+
     /**
      * Brings up an internal dialog panel with a specified icon, where
      * the initial choice is determined by the <code>initialValue</code>
@@ -1288,32 +1298,39 @@
                 getFocusOwner();
 
         pane.setInitialValue(initialValue);
-
-        JInternalFrame dialog =
-            pane.createInternalFrame(parentComponent, title);
-        pane.selectInitialValue();
-        dialog.setVisible(true);
+        if (checkFrameForComponent(parentComponent)) {
+            JInternalFrame dialog =
+                    pane.createInternalFrame(parentComponent, title);
+            pane.selectInitialValue();
+            dialog.setVisible(true);
 
-        /* Since all input will be blocked until this dialog is dismissed,
-         * make sure its parent containers are visible first (this component
-         * is tested below).  This is necessary for JApplets, because
-         * because an applet normally isn't made visible until after its
-         * start() method returns -- if this method is called from start(),
-         * the applet will appear to hang while an invisible modal frame
-         * waits for input.
-         */
-        if (dialog.isVisible() && !dialog.isShowing()) {
-            Container parent = dialog.getParent();
-            while (parent != null) {
-                if (parent.isVisible() == false) {
-                    parent.setVisible(true);
+            /* Since all input will be blocked until this dialog is dismissed,
+             * make sure its parent containers are visible first (this component
+             * is tested below).  This is necessary for JApplets, because
+             * because an applet normally isn't made visible until after its
+             * start() method returns -- if this method is called from start(),
+             * the applet will appear to hang while an invisible modal frame
+             * waits for input.
+             */
+            if (dialog.isVisible() && !dialog.isShowing()) {
+                Container parent = dialog.getParent();
+                while (parent != null) {
+                    if (parent.isVisible() == false) {
+                        parent.setVisible(true);
+                    }
+                    parent = parent.getParent();
                 }
-                parent = parent.getParent();
             }
+
+            AWTAccessor.getContainerAccessor().startLWModal(dialog);
+        } else {
+            pane.setComponentOrientation(getRootFrame().getComponentOrientation());
+            int style = styleFromMessageType(messageType);
+            JDialog dialog = pane.createDialog(parentComponent, title, style);
+            pane.selectInitialValue();
+            dialog.setVisible(true);
         }
 
-        AWTAccessor.getContainerAccessor().startLWModal(dialog);
-
         if (parentComponent instanceof JInternalFrame) {
             try {
                 ((JInternalFrame)parentComponent).setSelected(true);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JOptionPane/7042497/JOptionPaneConfirmDlgTest.java	Mon May 22 11:21:49 2017 +0530
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+/*
+ * @test
+ * @bug 7042497
+ * @summary  Verifies if JOptionPane.showInternalConfirmDialog
+             throws RuntimeException if parentComponent argument is null
+ * @run main/manual JOptionPaneConfirmDlgTest
+ */
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+
+public class JOptionPaneConfirmDlgTest {
+    JInternalFrame  textFrame;
+    JFrame f = null;
+
+    public static void main(String[] args) throws Exception{
+            new JOptionPaneConfirmDlgTest();
+    }
+
+    public JOptionPaneConfirmDlgTest() throws Exception {
+
+        try {
+            SwingUtilities.invokeAndWait(()->createGUI());
+            Thread.sleep(10000);
+        } finally {
+            SwingUtilities.invokeAndWait(()->f.dispose());
+        }
+
+    }
+
+    public void createGUI() {
+        JOptionPane.showMessageDialog(
+            (Component) null,
+            "An internalFrame with 2 buttons will be displayed. \n" +
+           " Press \"Hit me 1\" button. The bug causes a RuntimeException to be thrown here\n" +
+           " But If a confirmation dialog comes, test has passed\n" +
+           " Similarly, press \"Hit me 2\" button. The bug will cause a RuntimeException\n" +
+           " to be thrown here but if a confirmation dialog comes, test has passed.\n" +
+           " Close the dialog and frame.",
+            "information", JOptionPane.INFORMATION_MESSAGE);
+        f = new JFrame();
+
+        textFrame = new JInternalFrame("Main-Frame", true);
+        f.setContentPane(textFrame);
+
+        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
+        f.setSize(dim.width/6, dim.height/5);
+        textFrame.setBounds(10, 10, dim.width/8, dim.height/8);
+
+        textFrame.setVisible(true);
+
+        JButton b1 = new JButton("Hit me 1");
+        b1.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                JOptionPane.showInternalConfirmDialog(null, "Test?");
+            }});
+
+        JButton b2 = new JButton("Hit me 2");
+        b2.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                JOptionPane.showInternalConfirmDialog(new JInternalFrame(), "Test?");
+            }});
+
+        textFrame.setLayout(new FlowLayout());
+        textFrame.add(b1);
+        textFrame.add(b2);
+        f.setVisible(true);
+    }
+}