JDK-6738762 : Showing glassPane in non-opaque toplevel makes the topLevel blank
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 7
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2008-08-19
  • Updated: 2011-01-19
  • Resolved: 2008-09-02
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.
JDK 6
6u10 b31Fixed
Related Reports
Relates :  
Description
If a window was made non opaque with help of the
frame.setUndecorated(true);
AWTUtilities.setWindowOpaque(frame, false);

it is turned into the blank rectangle when glassPane is shown
frame.getGlassPane().setVisible(true);

I tested it on the latest JDK 6u11 build

GlassPane tricks are quite popular among Swing programmers
moreover this bug prevents resizing of internalFrames,
because we temporarily show the glassPane when an internalFrame is being resized

import com.sun.awt.AWTUtilities;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class GlassPanelTest {

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

        JButton button = new JButton("Show GlassPane");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                frame.getGlassPane().setVisible(true);
            }
        });
        
        frame.add(button);
        
        frame.setSize(200, 200);
        frame.setLocationRelativeTo(null);

        frame.setUndecorated(true);
        AWTUtilities.setWindowOpaque(frame, false);
        
        frame.setVisible(true);
    }

    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                GlassPanelTest.createGui();
            }
        });
    }
}

Comments
SUGGESTED FIX --- old/src/share/classes/java/awt/Window.java 2008-08-21 17:47:25.000000000 +0400 +++ new/src/share/classes/java/awt/Window.java 2008-08-21 17:47:25.000000000 +0400 @@ -3204,6 +3204,12 @@ Container c = root.getContentPane(); javax.swing.JComponent content = (c instanceof javax.swing.JComponent) ? (javax.swing.JComponent)c : null; + javax.swing.JComponent gp = + (rpc.getGlassPane() instanceof javax.swing.JComponent) ? + (javax.swing.JComponent)rpc.getGlassPane() : null; + if (gp != null) { + gp.setDoubleBuffered(isOpaque); + } lp.setOpaque(isOpaque); //lp.setDoubleBuffered(isOpaque); //XXX: this might be needed maybe... root.setOpaque(isOpaque);
21-08-2008

EVALUATION The problem is that the glass pane is double buffered by default. All components in non-opaque frames must be double-buffer-disabled (setDoubleBuffered(false)). To fix this issue we need to modify the Window.setLayersOpaque() method. The method must disable double-buffering on the glass pane (if any).
21-08-2008

EVALUATION When the window is non-opaque, and it needs to be repainted the sun.awt.windows.TranslucentWindowPainter (see src/windows/classes/sun/awt/windows/TranslucentWindowPainter.java) creates an ARGB_PRE buffered image and uses the Frame.paintAll(Graphics) method to paint the frame contents to the buffered image. The resulting image gets painted on the screen then. I modified the given test case so that the button action handler include the following code before and after setting the glass pane visible: BufferedImage i1 = new BufferedImage(frame.getWidth(), frame.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE);; frame.paintAll(i1.getGraphics()); try { javax.imageio.ImageIO.write(i1, "png", new File("before.png")); } catch (IOException e1) { e1.printStackTrace(); } (the one located after showing the glass pane saves the image to the after.png file.) The resulting files and the modified test case are attached to the change request. Obviously, the Swing paints the glass pane as an opaque panel, and therefore we observe this result on the screen. To fix the bug the Swing painting machinery must not paint the background of the glass pane (which is by default a non-opaque panel - it is unclear why Swing paints its background.).
20-08-2008