diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameManager.java b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameManager.java index 49a9a19d201..c2ce10b0e4a 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameManager.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameManager.java @@ -105,7 +105,9 @@ public class AquaInternalFrameManager extends DefaultDesktopManager { // Position depends on *current* position of frame, unlike super which reuses the first position final Rectangle r = getBoundsForIconOf(f); desktopIcon.setBounds(r.x, r.y, r.width, r.height); - + if (!wasIcon(f)) { + setWasIcon(f, Boolean.TRUE); + } c = f.getParent(); if (c == null) return; diff --git a/jdk/src/java.desktop/share/classes/javax/swing/JDesktopPane.java b/jdk/src/java.desktop/share/classes/javax/swing/JDesktopPane.java index 99a2fe8ab6a..e5d53e1cda3 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/JDesktopPane.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/JDesktopPane.java @@ -480,6 +480,7 @@ public class JDesktopPane extends JLayeredPane implements Accessible * @since 1.6 */ protected void addImpl(Component comp, Object constraints, int index) { + checkComponentAttributes(comp); super.addImpl(comp, constraints, index); if (componentOrderCheckingEnabled) { if (comp instanceof JInternalFrame || @@ -489,6 +490,12 @@ public class JDesktopPane extends JLayeredPane implements Accessible } } + private void checkComponentAttributes(Component comp) { + if (comp instanceof JInternalFrame && ((JInternalFrame) comp).isIcon()) { + ((JInternalFrame) comp).putClientProperty("wasIconOnce", Boolean.FALSE); + } + } + /** * {@inheritDoc} * @since 1.6 diff --git a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java index b185d785a25..bcae2e3f8e8 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java @@ -1710,6 +1710,12 @@ public class BasicInternalFrameUI extends InternalFrameUI } else { parentBounds = null; } + if ((frame.getParent() != null) && frame.isIcon()) { + Boolean value = (Boolean) frame.getClientProperty("wasIconOnce"); + if (Boolean.FALSE.equals(value)) { + iconifyFrame(frame); + } + } if ((frame.getParent() != null) && !componentListenerAdded) { f.getParent().addComponentListener(componentListener); componentListenerAdded = true; diff --git a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDesktopPaneUI.java b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDesktopPaneUI.java index 6259171317b..b22941c8f6f 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDesktopPaneUI.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDesktopPaneUI.java @@ -351,12 +351,16 @@ public class SynthDesktopPaneUI extends BasicDesktopPaneUI implements Container c = f.getParent(); JDesktopPane d = f.getDesktopPane(); boolean findNext = f.isSelected(); - - if (c == null) { + if (c == null || d == null) { return; } - desktopIcon = f.getDesktopIcon(); + if (!wasIcon(f)) { + Rectangle r = getBoundsForIconOf(f); + desktopIcon.setBounds(r.x, r.y, r.width, r.height); + desktopIcon.revalidate(); + setWasIcon(f, Boolean.TRUE); + } if (!f.isMaximum()) { f.setNormalBounds(f.getBounds()); diff --git a/jdk/test/javax/swing/JInternalFrame/4769772/TestJInternalFrameIconify.java b/jdk/test/javax/swing/JInternalFrame/4769772/TestJInternalFrameIconify.java new file mode 100644 index 00000000000..12bd49d1b49 --- /dev/null +++ b/jdk/test/javax/swing/JInternalFrame/4769772/TestJInternalFrameIconify.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015, 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 4769772 + * @summary JInternalFrame.setIcon(true) before JDesktopPane.add(JIF) causes wrong state + * @run main TestJInternalFrameIconify + */ +import java.beans.PropertyVetoException; +import javax.swing.JFrame; +import javax.swing.JDesktopPane; +import javax.swing.JInternalFrame; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; +import java.awt.Robot; +import javax.swing.SwingUtilities; + +public class TestJInternalFrameIconify { + + private static JDesktopPane desktopPane; + private static JFrame frame; + private static Robot robot; + private static volatile String errorMessage = ""; + + public static void main(String[] args) throws Exception { + robot = new java.awt.Robot(); + UIManager.LookAndFeelInfo[] lookAndFeelArray + = UIManager.getInstalledLookAndFeels(); + for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) { + String lookAndFeelString = lookAndFeelItem.getClassName(); + if (tryLookAndFeel(lookAndFeelString)) { + createUI(lookAndFeelString); + robot.waitForIdle(); + executeTest(lookAndFeelString); + } + } + if (!"".equals(errorMessage)) { + throw new RuntimeException(errorMessage); + } + } + + private static boolean tryLookAndFeel(String lookAndFeelString) { + try { + UIManager.setLookAndFeel(lookAndFeelString); + return true; + } catch (UnsupportedLookAndFeelException | ClassNotFoundException | + InstantiationException | IllegalAccessException e) { + errorMessage += e.getMessage() + "\n"; + System.err.println("Caught Exception: " + e.getMessage()); + return false; + } + } + + private static void createUI(String lookAndFeelString) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + frame = new JFrame(lookAndFeelString); + desktopPane = new JDesktopPane(); + frame.getContentPane().add(desktopPane); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + JInternalFrame f = new JInternalFrame("Child ", true, true, + true, true); + f.setSize(200, 300); + f.setLocation(20, 20); + try { + f.setIcon(true); + } catch (PropertyVetoException ex) { + errorMessage += ex.getMessage() + "\n"; + } + desktopPane.add(f); + f.setVisible(true); + + frame.setSize(500, 500); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + }); + + } + + private static void executeTest(String lookAndFeelString) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + try { + JInternalFrame internalFrames[] + = desktopPane.getAllFrames(); + if (internalFrames[0].isShowing()) { + errorMessage += "Test Failed for " + + lookAndFeelString + " look and feel\n"; + System.err.println(errorMessage); + } + } finally { + frame.dispose(); + } + } + }); + } +}