JDK-6637655 : Mixing of heavyweight/lightweight components does not wrk with GlassPane childre
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6u12,7
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-12-05
  • Updated: 2011-01-19
  • Resolved: 2009-02-19
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 JDK 7
6u12Fixed 7 b48Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b22)
Java HotSpot(TM) Client VM (build 11.0-b08, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP Professional Service Pack 2

A DESCRIPTION OF THE PROBLEM :
JDK 7 supports mixing of heavyweight and lightweight components (currently based on isOpaque() return value of lightweight components). That feature does not seem to work for children of GlassPane. See the test program.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Execute the following program.
2. Drop down the menu
3. Observer how the drop down Menu, JInternalFrame and the heavyweight button get painted.

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLayeredPane;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

public class TestFrame {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JMenuBar menuBar = new JMenuBar();
        frame.setJMenuBar(menuBar);
        JMenu menu = new JMenu("Menu");
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menuBar.add(menu);
        
        // LAYERED PANE SECTION
//        JLayeredPane layeredPane = frame.getRootPane().getLayeredPane();
//        JInternalFrame internalFrame = new JInternalFrame("Internal Frame", true);
//        internalFrame.setBounds(50, 50, 200, 100);
//        internalFrame.setVisible(true);
//        layeredPane.add(internalFrame, JLayeredPane.PALETTE_LAYER);
        
        // GLASSPANE PANE SECTION
        JPanel glassPane = (JPanel) frame.getRootPane().getGlassPane();
        glassPane.setVisible(true);
        glassPane.setLayout(null);
        JInternalFrame internalFrame = new JInternalFrame("Internal Frame", true);
        internalFrame.setBounds(50, 0, 200, 100);
        internalFrame.setVisible(true);
        glassPane.add(internalFrame);
        
        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(new Button("Heavyweight Button"));
        frame.setSize(400, 400);
        frame.setVisible(true);
    }
}

If you comment out the GLASSPANE SECTION and uncomment the LAYERED PANE section and then execute the program that works well.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect to see the full JInternalFrame.
ACTUAL -
The JInternalFrame is being clicpped by the HeavyWeight button.

If you want to use the glasspane for what it is intended for this is a huge problem.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
mport java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLayeredPane;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

public class TestFrame {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JMenuBar menuBar = new JMenuBar();
        frame.setJMenuBar(menuBar);
        JMenu menu = new JMenu("Menu");
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menu.add(new JMenuItem("Menu Item"));
        menuBar.add(menu);
        
        // LAYERED PANE SECTION
//        JLayeredPane layeredPane = frame.getRootPane().getLayeredPane();
//        JInternalFrame internalFrame = new JInternalFrame("Internal Frame", true);
//        internalFrame.setBounds(50, 50, 200, 100);
//        internalFrame.setVisible(true);
//        layeredPane.add(internalFrame, JLayeredPane.PALETTE_LAYER);
        
        // GLASSPANE PANE SECTION
        JPanel glassPane = (JPanel) frame.getRootPane().getGlassPane();
        glassPane.setVisible(true);
        glassPane.setLayout(null);
        JInternalFrame internalFrame = new JInternalFrame("Internal Frame", true);
        internalFrame.setBounds(50, 0, 200, 100);
        internalFrame.setVisible(true);
        glassPane.add(internalFrame);
        
        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(new Button("Heavyweight Button"));
        frame.setSize(400, 400);
        frame.setVisible(true);
    }
}

---------- END SOURCE ----------

Comments
EVALUATION The problem appears beacuse of the fact that the mixing code simply ignores any component that is setOpaqe(false)'ed. The GlassPane is obviously non-opaque, and hence the mixing code doesn't take it into account, nor it takes into account the children of the GlassPane. One possible solution to this is to rework the mixing code algorithms that iterate over the component hierarchy, and look for any opaque children even in non-opaque containers.
05-12-2007