Java - JMenuBar Hidden When Using Glass Pane

539 views Asked by At

The problem seems simple, but I can't seem to get around it.

I am using GlassPane in my frame (also the ContentPane). So when I add JMenuBar to the frame it doesn't show up. If/when I am using GlassPane at other times, everything works absolutely fine. I did some research, what I understand is that JMenuBar is shown on RootPane and I believe GlassPane is somehow hiding it.

I need to know if there is any way to get JMenuBar while using glassPane?

Thanks

UPDATE: I am setting glassPane.setOpaque(false)

UPDATE:

The actual lines of code are much more but here are the ones that are relative to the problem. (mainPanel and notificationPanel are self constructed classes extending from JPanel)

public class Demo extends JFrame {

/////////////////////////////////////////////////////////////////////////
// JMenuBar
private final JMenuBar mainMenuBar;
    private final JMenu fileMenu;
        private final JMenuItem exitFileMenu;
/////////////////////////////////////////////////////////////////////////
// CONTENT PANE & COMPONENTS
private final JPanel contentPanel;
    private final JPanel buttonPanel;
        private final JButton button1;

/////////////////////////////////////////////////////////////////////////
// GLASSPANE AND COMPONENTS
private final JPanel glassPanel;
    private final JPanel buttonPanel2;
    private final JButton button2;

public Demo() {
    super();

    this.mainMenuBar = new JMenuBar();
        this.fileMenu = new JMenu("File");
            this.exitFileMenu = new JMenuItem("EXIT");

    this.contentPanel = new JPanel(new BorderLayout());
        this.buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
            this.button1 = new JButton("Button 1");

    this.glassPanel = new JPanel(new BorderLayout());
        this.buttonPanel2 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
            this.button2 = new JButton("Button 2");
}

public void initGUI() {
        this.fileMenu.add(this.exitFileMenu);
    this.mainMenuBar.add(this.fileMenu);

        this.buttonPanel.add(this.button1);
    this.contentPanel.add(this.buttonPanel, BorderLayout.NORTH);


        this.buttonPanel2.add(this.button2);
    this.glassPanel.add(this.buttonPanel2, BorderLayout.NORTH);

    super.setContentPane(this.contentPanel);
    super.setGlassPane(this.glassPanel);

    this.glassPanel.setOpaque(false);
    this.glassPanel.setVisible(true);

    super.setExtendedState(JFrame.MAXIMIZED_BOTH);
    super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    super.setJMenuBar(mainMenuBar);
    super.setVisible(true);
}

public static void main(String[] args) {
    Demo obj = new Demo();
    obj.initGUI();
}

}

2

There are 2 answers

0
Abbas On BEST ANSWER

Alright guys I accidentally found the solution to the problem. It was in-fact simple, if you are using nested Panels within the 'glassPane' then simply set each nested panel's opacity to false. If you don't the nested panels will show its background to each of its bounds and overlap any underlying layer(s).

Here's the working code of the above Demo.

public class Demo extends JFrame {

/////////////////////////////////////////////////////////////////////////
// JMenuBar
private final JMenuBar mainMenuBar;
    private final JMenu fileMenu;
        private final JMenuItem exitFileMenu;
/////////////////////////////////////////////////////////////////////////
// CONTENT PANE & COMPONENTS
private final JPanel contentPanel;
    private final JPanel buttonPanel;
        private final JButton button1;

/////////////////////////////////////////////////////////////////////////
// GLASSPANE AND COMPONENTS
private final JPanel glassPanel;
    private final JPanel buttonPanel2;
    private final JButton button2;

public Demo() {
    super();

    this.mainMenuBar = new JMenuBar();
        this.fileMenu = new JMenu("File");
            this.exitFileMenu = new JMenuItem("EXIT");

    this.contentPanel = new JPanel(new BorderLayout());
        this.buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
            this.button1 = new JButton("Button 1");

    this.glassPanel = new JPanel(new BorderLayout());
        this.buttonPanel2 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
            this.button2 = new JButton("Button 2");
}

public void initGUI() {
        this.fileMenu.add(this.exitFileMenu);
    this.mainMenuBar.add(this.fileMenu);

        this.buttonPanel.add(this.button1);
    this.contentPanel.add(this.buttonPanel, BorderLayout.NORTH);


        this.buttonPanel2.add(this.button2);
        this.buttonPanel2.setOpaque(false);
    this.glassPanel.add(this.buttonPanel2, BorderLayout.NORTH);

    super.setContentPane(this.contentPanel);
    super.setGlassPane(this.glassPanel);

    this.glassPanel.setOpaque(false);
    this.glassPanel.setVisible(true);

    super.setExtendedState(JFrame.MAXIMIZED_BOTH);
    super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    super.setJMenuBar(mainMenuBar);
    super.setVisible(true);
}

public static void main(String[] args) {
    Demo obj = new Demo();
    obj.initGUI();
}

}

Now Also remember always to set the glassPane's Opacity after you call 'setGlassPane(JPanel)' Otherwise the GlassPane remain Opaque. (The nested Panels you may set before or after calling the said method)

4
BluesSolo On

You are using BorderLayout and the option BorderLayout.NORTH for your glassPanel. It takes the entire space in the north and it overlaps your entire menu. Therefore you don't see anything anymore. Change for example your panel creation into:

this.glassPanel = new JPanel();

Then your panel will be resized to only fit your button and you will see your menu behind. You can play around with some layouts and see which one fits. But just remember that the glass pane is always on top of everything. Just a little side note: When you add your button directly to 'glassPanel' (without using 'buttonPanel2') you can remove the little "borders". Otherwise you could resize it to perfectly fit your button. Both is possible, but if you only want to have a single component (like your button) then I would add it directly.