United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6637655 Mixing of heavyweight/lightweight components does not wrk with GlassPane childre
JDK-6637655 : Mixing of heavyweight/lightweight components does not wrk with GlassPane childre

Details
Type:
Bug
Submit Date:
2007-12-05
Status:
Resolved
Updated Date:
2011-01-19
Project Name:
JDK
Resolved Date:
2009-02-19
Component:
client-libs
OS:
windows_xp
Sub-Component:
java.awt
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
6u12,7
Fixed Versions:

Related Reports
Backport:
Duplicate:
Duplicate:
Relates:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

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.
                                     
2007-12-05



Hardware and Software, Engineered to Work Together