JDK-4176733 : REGRESSION: JDesktopPane setVisible(true) need before adding JInternalFrames
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.1.6,1.2.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS:
    generic,solaris_2.6,windows_95,windows_nt generic,solaris_2.6,windows_95,windows_nt
  • CPU: generic,x86,sparc
  • Submitted: 1998-09-28
  • Updated: 1998-12-02
  • Resolved: 1998-10-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.2.2 1.2.2Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Description

Name: clC74495			Date: 09/28/98


JDesktopPane simply _does not work_ in Swing 1.1 beta 3.  This problem
exists for all Look and Feels, including our own custom one.  JInternalFrames
added to the desktop pane using .add() never show up.

This problem does not exist in Swing 1.0.2.

Simply by commenting out the javax.swing line and uncommenting the 
com.sun.java.swing one (and changing the classpath), the following
example works in Swing 1.0.2/1.0.3.  It fails very obviously in Swing 1.1
(the JInternalFrame never shows up).

This problem also has the very odd side effect of causing Look and Feel
initialization done around the same time as the .add() to fail.

We've traced though JLayeredPane.addImpl() and the JInternalFrame is
being added (and is in a correct layer, and is the only component in the
JDesktopPane), so we're stumped as to what is going wrong.  The only 
workaround we've found is removing the JDesktopPane and adding the
JInternalFrame directly to a panel, which is awful.

It would be _very, very_ bad if something this widely used and so 
basic was broken in the public release of 1.1b3.

package jfilechooser;

import java.awt.*;
//import com.sun.java.swing.*;
import javax.swing.*;

public class MyClass1 extends JFrame {

  public MyClass1() {
    JDesktopPane jdp = new JDesktopPane();
    this.getContentPane().add(jdp, BorderLayout.CENTER);
    JInternalFrame jif = new JInternalFrame("A Frame");
    jdp.add(jif, JDesktopPane.DEFAULT_LAYER);
    try
    {
      jif.setMaximum(true);
    }
    catch (java.beans.PropertyVetoException pve)
    {}
    
    jif.setVisible(true);
  }

  public static void main(String[] args) {
    MyClass1 myClass1 = new MyClass1();
    myClass1.setSize(640,480);
    myClass1.setVisible(true);
  }
}
(Review ID: 39415)
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: generic FIXED IN: 1.2.2 swing2.0alpha INTEGRATED IN: 1.2.2 swing2.0alpha
14-06-2004

WORK AROUND /** * 4172978: workaround for problem with a maximized JInternalFrame not * tracking parent frame size changes. */ import javax.swing.*; import javax.swing.plaf.*; import java.awt.*; import java.awt.event.*; import java.beans.*; // Substitute other L&F class if necessary, such as WindowsInternalFrameUI. import javax.swing.plaf.metal.MetalInternalFrameUI; public class InternalFrameTest extends JFrame { InternalFrameTest() { /* * Create a frame which has a desktop pane with a single internal frame. */ super("JInternalFrame test"); JDesktopPane jdp = new JDesktopPane(); getContentPane().add("Center", jdp); JInternalFrame jframe = new JInternalFrame("Test", true, true, true, true); jframe.setSize(150, 100); jdp.add(jframe, JLayeredPane.PALETTE_LAYER); setSize(500, 400); validate(); } /** * Override MetalInternalFrameUI to fix how it tracks the size of its * desktop pane when maximized. What's needed is a ComponentListener * which tracks componentResized events, but there's a complication in * that when the UI is being installed, its associated internal frame * usually doesn't have a desktop pane yet. Watch PropertyChangeEvents * will give us a chance to add the listener before the app is realized. */ public static class MyInternalFrameUI extends MetalInternalFrameUI implements PropertyChangeListener { public static ComponentUI createUI(JComponent b) { return new MyInternalFrameUI((JInternalFrame)b); } JInternalFrame frame = null; boolean listenerAdded = false; public MyInternalFrameUI(JInternalFrame jif) { super(jif); frame = jif; jif.addPropertyChangeListener(this); } // PropertyChanges are watched so that the ComponentListener can be // added as soon as there's a desktop pane to listen to. public void propertyChange(PropertyChangeEvent evt) { JDesktopPane desktop = frame.getDesktopPane(); if (!listenerAdded && desktop != null) { desktop.addComponentListener(new ComponentAdapter() { // Track the desktop pane's size when frame is maximized. public void componentResized(ComponentEvent e) { if (frame.isMaximum()) { Dimension d = ((Component)e.getSource()).getSize(); frame.setBounds(0, 0, d.width, d.height); frame.validate(); } } }); listenerAdded = true; } } } public static void main(String[] args) { // Override the MetalInternalFrameUI with one with a fixed // componentResized method. UIManager.getLookAndFeel(); // force L&F to initialize UIManager.put("InternalFrameUI", "InternalFrameTest$MyInternalFrameUI"); JFrame frame = new InternalFrameTest(); frame.show(); } }
11-06-2004

SUGGESTED FIX There is a shadow bug in the java_solaris/awt category. This bug has been fixed in the JDK1.2 dev05 release by the Java Technologies Group. This bug does not seem to be fixed in the reference JDK1.2FCS-U build. To see get the fix, see the following files/deltas in the JTG workspace... update: src/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java 1.50 I can provide these if you like. james.melvin@East 1998-11-27
27-11-1998

EVALUATION I've just looked at this quickly and see the regression. I do have a simple workaround: Call setSize(w,h) and setVisible(true) *BEFORE* adding the JInternalFrames to the desktopPane. I surmise since most all of our demos and test code I use are coded this way, the problem wasn't seen in the latest releases. . . richard.schiavi@Eng 1998-09-28 Here is a dump of a good vs bad compnent list. the one with a setSize/setVisible has the correct size for the JinternalFrame. The other has it at 0x0 9setVisible() setVisible() fire openend FrameDemo[frame0,1,1,640x480,layout=java.awt.BorderLayout,resizable,title=,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,5,24,630x451,layout=javax.swing.JRootPane$RootLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true] javax.swing.JRootPane[,5,24,630x451,layout=javax.swing.JRootPane$RootLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=] javax.swing.JPanel[null.glassPane,0,0,630x451,hidden,layout=java.awt.FlowLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=,defaultLayout=java.awt.FlowLayout[hgap=5,vgap=5,align=center]] javax.swing.JLayeredPane[null.layeredPane,0,0,630x451,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=true] javax.swing.JPanel[null.contentPane,0,0,630x451,layout=javax.swing.JRootPane$1,alignmentX=null,alignmentY=null,border=,flags=34,maximumSize=,minimumSize=,preferredSize=,defaultLayout=java.awt.FlowLayout[hgap=5,vgap=5,align=center]] javax.swing.JDesktopPane[,0,0,630x451,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=false,desktopManager=javax.swing.DefaultDesktopManager@1dc612be] javax.swing.JInternalFrame[,0,0,629x450,layout=javax.swing.plaf.basic.BasicInternalFrameUI$InternalFrameLayout,alignmentX=null,alignmentY=null,border=javax.swing.plaf.metal.MetalBorders$InternalFrameBorder@1dc61504,flags=32,maximumSize=,minimumSize=java.awt.Dimension[width=120,height=24],preferredSize=,closable=false,defaultCloseOperation=HIDE_ON_CLOSE,desktopIcon=javax.swing.JInternalFrame$JDesktopIcon[,0,0,84x30,invalid,layout=java.awt.BorderLayout,alignmentX=null,alignmentY=null,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@1dc61a7f,flags=32,maximumSize=,minimumSize=,preferredSize=],frameIcon=javax.swing.plaf.metal.MetalIconFactory$InternalFrameDefaultMenuIcon@1dc614f9,iconable=false,isClosed=false,isIcon=false,isMaximum=true,isSelected=true,maximizable=false,opened=true,resizable=false,rootPane=javax.swing.JRootPane[,5,26,619x419,layout=javax.swing.JRootPane$RootLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true,title=Test] javax.swing.JRootPane[,5,26,619x419,layout=javax.swing.JRootPane$RootLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=] javax.swing.JPanel[null.glassPane,0,0,619x419,hidden,layout=java.awt.FlowLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=,defaultLayout=java.awt.FlowLayout[hgap=5,vgap=5,align=center]] javax.swing.JLayeredPane[null.layeredPane,0,0,619x419,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=true] javax.swing.JPanel[null.contentPane,0,0,619x419,layout=javax.swing.JRootPane$1,alignmentX=null,alignmentY=null,border=javax.swing.border.EmptyBorder@1dc610f1,flags=34,maximumSize=,minimumSize=,preferredSize=,defaultLayout=java.awt.FlowLayout[hgap=5,vgap=5,align=center]] javax.swing.plaf.metal.MetalInternalFrameTitlePane[,5,5,619x21,layout=javax.swing.plaf.metal.MetalInternalFrameTitlePane,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=] FrameDemo[frame0,1,1,640x480,layout=java.awt.BorderLayout,resizable,title=,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,5,24,630x451,layout=javax.swing.JRootPane$RootLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true] javax.swing.JRootPane[,5,24,630x451,layout=javax.swing.JRootPane$RootLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=] javax.swing.JPanel[null.glassPane,0,0,630x451,hidden,layout=java.awt.FlowLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=,defaultLayout=java.awt.FlowLayout[hgap=5,vgap=5,align=center]] javax.swing.JLayeredPane[null.layeredPane,0,0,630x451,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=true] javax.swing.JPanel[null.contentPane,0,0,630x451,layout=javax.swing.JRootPane$1,alignmentX=null,alignmentY=null,border=,flags=34,maximumSize=,minimumSize=,preferredSize=,defaultLayout=java.awt.FlowLayout[hgap=5,vgap=5,align=center]] javax.swing.JDesktopPane[,0,0,630x451,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=false,desktopManager=javax.swing.DefaultDesktopManager@1dc612be] javax.swing.JInternalFrame[,0,0,629x450,layout=javax.swing.plaf.basic.BasicInternalFrameUI$InternalFrameLayout,alignmentX=null,alignmentY=null,border=javax.swing.plaf.metal.MetalBorders$InternalFrameBorder@1dc61504,flags=32,maximumSize=,minimumSize=java.awt.Dimension[width=120,height=24],preferredSize=,closable=false,defaultCloseOperation=HIDE_ON_CLOSE,desktopIcon=javax.swing.JInternalFrame$JDesktopIcon[,0,0,84x30,invalid,layout=java.awt.BorderLayout,alignmentX=null,alignmentY=null,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@1dc61a7f,flags=32,maximumSize=,minimumSize=,preferredSize=],frameIcon=javax.swing.plaf.metal.MetalIconFactory$InternalFrameDefaultMenuIcon@1dc614f9,iconable=false,isClosed=false,isIcon=false,isMaximum=true,isSelected=true,maximizable=false,opened=true,resizable=false,rootPane=javax.swing.JRootPane[,5,26,619x419,layout=javax.swing.JRootPane$RootLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true,title=Test] javax.swing.JRootPane[,5,26,619x419,layout=javax.swing.JRootPane$RootLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=] javax.swing.JPanel[null.glassPane,0,0,619x419,hidden,layout=java.awt.FlowLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=,defaultLayout=java.awt.FlowLayout[hgap=5,vgap=5,align=center]] javax.swing.JLayeredPane[null.layeredPane,0,0,619x419,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=true] javax.swing.JPanel[null.contentPane,0,0,619x419,layout=javax.swing.JRootPane$1,alignmentX=null,alignmentY=null,border=javax.swing.border.EmptyBorder@1dc610f1,flags=34,maximumSize=,minimumSize=,preferredSize=,defaultLayout=java.awt.FlowLayout[hgap=5,vgap=5,align=center]] javax.swing.plaf.metal.MetalInternalFrameTitlePane[,5,5,619x21,layout=javax.swing.plaf.metal.MetalInternalFrameTitlePane,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=] ******NO INTERNALFRAME SHOWN: setVisible() setVisible() fire openend FrameDemo[frame0,1,1,640x480,layout=java.awt.BorderLayout,resizable,title=,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,5,24,630x451,layout=javax.swing.JRootPane$RootLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true] javax.swing.JRootPane[,5,24,630x451,layout=javax.swing.JRootPane$RootLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=] javax.swing.JPanel[null.glassPane,0,0,630x451,hidden,layout=java.awt.FlowLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=,defaultLayout=java.awt.FlowLayout[hgap=5,vgap=5,align=center]] javax.swing.JLayeredPane[null.layeredPane,0,0,630x451,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=true] javax.swing.JPanel[null.contentPane,0,0,630x451,layout=javax.swing.JRootPane$1,alignmentX=null,alignmentY=null,border=,flags=34,maximumSize=,minimumSize=,preferredSize=,defaultLayout=java.awt.FlowLayout[hgap=5,vgap=5,align=center]] javax.swing.JDesktopPane[,0,0,630x451,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=false,desktopManager=javax.swing.DefaultDesktopManager@1dc61236] javax.swing.JInternalFrame[,0,0,0x0,layout=javax.swing.plaf.basic.BasicInternalFrameUI$InternalFrameLayout,alignmentX=null,alignmentY=null,border=javax.swing.plaf.metal.MetalBorders$InternalFrameBorder@1dc613b1,flags=32,maximumSize=,minimumSize=java.awt.Dimension[width=120,height=24],preferredSize=,closable=false,defaultCloseOperation=HIDE_ON_CLOSE,desktopIcon=javax.swing.JInternalFrame$JDesktopIcon[,0,0,84x30,invalid,layout=java.awt.BorderLayout,alignmentX=null,alignmentY=null,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@1dc61a7a,flags=32,maximumSize=,minimumSize=,preferredSize=],frameIcon=javax.swing.plaf.metal.MetalIconFactory$InternalFrameDefaultMenuIcon@1dc613ad,iconable=false,isClosed=false,isIcon=false,isMaximum=true,isSelected=true,maximizable=false,opened=true,resizable=false,rootPane=javax.swing.JRootPane[,5,26,-10x-31,layout=javax.swing.JRootPane$RootLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true,title=Test] javax.swing.JRootPane[,5,26,-10x-31,layout=javax.swing.JRootPane$RootLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=] javax.swing.JPanel[null.glassPane,0,0,-10x-31,hidden,layout=java.awt.FlowLayout,alignmentX=null,alignmentY=null,border=,flags=2,maximumSize=,minimumSize=,preferredSize=,defaultLayout=java.awt.FlowLayout[hgap=5,vgap=5,align=center]] javax.swing.JLayeredPane[null.layeredPane,0,0,-10x-31,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=true] javax.swing.JPanel[null.contentPane,0,0,-10x-31,layout=javax.swing.JRootPane$1,alignmentX=null,alignmentY=null,border=javax.swing.border.EmptyBorder@1dc6149f,flags=34,maximumSize=,minimumSize=,preferredSize=,defaultLayout=java.awt.FlowLayout[hgap=5,vgap=5,align=center]] javax.swing.plaf.metal.MetalInternalFrameTitlePane[,5,5,-10x21,layout=javax.swing.plaf.metal.MetalInternalFrameTitlePane,alignmentX=null,alignmentY=null,border=,flags=0,maximumSize=,minimumSize=,preferredSize=] richard.schiavi@Eng 1998-09-30 i've found it: d'oh! in the plaf cleanup, the ComponentListener was moved from the J class into the UI, which was correct. The listener is added in the frame.setMaximize to the desktop to monitor resizes. Here is the incorrect code with the bug! public void componentResized(ComponentEvent e) { Dimension d = ((Component)e.getSource()).getSize(); ((Component)e.getSource()).setBounds(0, 0, d.width, d.height); ((Component)e.getSource()).validate(); } We get the resize event on the desktop, but incorectly, set the bounds and validate the wrong target! we should validate and set the bounds on the frame, not the desktop (which is the e.getSource in this case!!) richard.schiavi@Eng 1998-09-30
30-09-1998