JDK-6690014 : JInternalFrame can't be closed, iconified or deiconifed if its parent differs from JDesktopPane
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-04-17
  • Updated: 2014-03-11
  • Resolved: 2014-03-11
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_04"
Java(TM) SE Runtime Environment (build 1.6.0_04-b12)
Java HotSpot(TM) Client VM (build 10.0-b19, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
A JInternalFrame added to the layered pane of a JApplet cannot be iconified anymore in Java SE 6.

I found the problem in the source code, class javax.swing.DefaultDesktopManager, in method iconifyFrame(JInternalFrame f); inside this method, a check for a null Container c  only (in Java SE 5) was changed to a check for a null container c OR a null JDesktopPane d:

if (c == null || d == null) {
    return;
}

(line 164 of source code of class javax.swing.DefaultDesktopManager)

But a JInternalFrame attached to a JApplet will always return "null" for getDesktopPane(), so iconifyFrame method returns in Java SE 6 without performing the actual iconify.


REPRODUCIBILITY :
This bug can be reproduced always.

Release Regression From : 5.0
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.
JInternalFrame can't be closed, iconified or deiconifed if its parent differs from JDesktopPane. This behavior doesn't comply the JInternalFrame specs. It is declared that an internal frame can be added to any Container. However, after the fix for 6325652 an internal frame can be closed, iconified or deiconifed only when its parent is JDesktopPane.

Test case:
==== Source Begin ====
import javax.swing.*;

public class InternalFrameCloseTest {
    private static JFrame frame;
    private static JInternalFrame iFrame;
    private static boolean testPassed = true;

    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
                setupUI();
            }
        });
        SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
                iFrame.dispose();
            }
        });
        SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
                if (frame.getContentPane().getComponentCount() == 1) {
                    testPassed = false;
                }
            }
        });

        try {
            if (testPassed) {
                System.out.println("Test passed");
            } else {
                throw new RuntimeException("JInternalFrame cannot be " +
                        "properly closed if its parent differs from JDesktopPane");
            }
        } finally {
            frame.dispose();
        }
    }

    private static void setupUI() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().setLayout(null);
        frame.setSize(400, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        iFrame = new JInternalFrame("Internal frame", true, true, true, true);
        frame.getContentPane().add(iFrame);
        iFrame.setSize(200, 100);
        iFrame.setLocation(50, 50);
        iFrame.setVisible(true);
    }
}
==== Source End ====

Comments
SUGGESTED FIX A possible fix is in the attachment.
25-06-2008

EVALUATION Probably, to fix the problem the following approach can be applied. If there is no JDesktopPane, the code that was replaced by the fix for 6325652 can be used.
23-05-2008

EVALUATION Author's comments for the changes in DefaultDesktopManager.java, which caused the regression: The implementation of closeFrame, iconifyFrame, deiconifyFrame, were modified to make sure the frame selection is correctly maintained. closeFrame calls getNextFrame to get the next frame using the stacking order from the JDesktopPane.
22-05-2008

EVALUATION First of all, such usage of internal frames out of JDesktopPane is not recommended. The bug is a result of the fix for 6325652. Webrev: http://sa.sfbay.sun.com/projects/swing_data/6.0/6325652/src/share/classes/javax/swing/DefaultDesktopManager.java.sdiff.html The fix solves problems with focus and mnemonics. It uses JDesktopPane to do it. Thus JDesktopPane presence became required by the following methods of DefaultDesktopManager: - closeFrame - iconifyFrame - deiconifyFrame This behavior doesn't comply the JInternalFrame specs. It is declared that an internal frame can be added to any Container. However, after the fix for 6325652 an internal frame can be closed, iconified or deiconifed only when its parent is JDesktopPane.
21-05-2008