Menu Appearing Behind Other Components

Hello all,

I am relatively new to Java Swing (a PHP developer with some JSP experience) and I am having some trouble following some code. The original application given in the tutorial does not have a menu bar so I was trying to add one. I've added menu bars to other projects in the past, but for some reason every time I try to add a menu bar using theFrame.setJMenuBar(menuBar), the menu appears but the pop-up menus appear behind other components. Here is the relative code all within a buildGUI() method, all variables are properly scoped and the project compiles fine:

theFrame =new JFrame("Test Application");

theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

BorderLayout layout =new BorderLayout();

JPanel background =new JPanel(layout);

background.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));

//setup the menu and add the action listeners

JMenuBar menuBar =new JMenuBar();

JMenu fileMenu =new JMenu("File");

JMenuItem saveMenuItem =new JMenuItem("Save");

JMenuItem newMenuItem =new JMenuItem("New");

JMenuItem loadMenuItem =new JMenuItem("Load");

saveMenuItem.addActionListener(new SaveListener());

loadMenuItem.addActionListener(new LoadListener());

newMenuItem.addActionListener(new NewListener());

fileMenu.add(newMenuItem);

fileMenu.add(saveMenuItem);

fileMenu.add(loadMenuItem);

menuBar.add(fileMenu);

//snip code adding boxes and checkboxes to panels

background.add(BorderLayout.EAST, buttonBox);

background.add(BorderLayout.WEST, nameBox);

theFrame.getContentPane().add(background);

GridLayout grid =new GridLayout(16,16);

grid.setVgap(1);

grid.setHgap(2);

mainPanel =new JPanel(grid);//create a panel to hold boxes

background.add(BorderLayout.CENTER, mainPanel);//add panel

theFrame.setBounds(50,50,310,310);

theFrame.setJMenuBar(menuBar);

theFrame.pack();

theFrame.setVisible(true);

I could post more but didn't want to make the post stretch out too long. Thanks in advance for your help!

-Kevin

[2868 byte] By [LosingTheFighta] at [2007-11-27 6:15:18]
# 1
Most likely these other components are not Swing components but rather AWT components. Mixing Swing with AWT will result in behavior like that.
dwga at 2007-7-12 17:25:43 > top of Java-index,Java Essentials,New To Java...
# 2
You can fix this by making the menu a heavy weight component.JPopupMenu.setDefaultLightWeightPopupEnabled(true);But, as said above, you really shouldn't be mixing Swing and AWT.
CaptainMorgan08a at 2007-7-12 17:25:43 > top of Java-index,Java Essentials,New To Java...
# 3

I don't think that is the issue (no offense). I have gone through and made sure that all of my components were swing (JCheckBox, JPanel, etc). I even tried adding the components directly to the frame as opposed to a JPanel then onto the frame. I know in the "real world" I will probably just be using a GUI editor (like Matisse) but I wanted to try to nail this down, both for my benefit and in case I have to hand code a GUI in the future in a real project. I appreciate your help though.

LosingTheFighta at 2007-7-12 17:25:43 > top of Java-index,Java Essentials,New To Java...
# 4
See if the line of code I gave you works. If it does, then chances are you do have an AWT component somewhere.
CaptainMorgan08a at 2007-7-12 17:25:43 > top of Java-index,Java Essentials,New To Java...
# 5

I tired placing the line of code given but still had the same problem. I appreciate your help, but that didn't solve it. I am probably not describing the problem correctly. Here is a link to an image I uploaded real quick:

http://kevineaton.net/problemMenu.png

As you can see, when the File menu is selected, the Menu, and all of the MenuItems, appear behind the JPanel. Please forgive me if I am confusing my terminology as I am new to client-side Java development (I am trying my best to learn though!).

Thanks!

-Kev

LosingTheFighta at 2007-7-12 17:25:43 > top of Java-index,Java Essentials,New To Java...
# 6
Time to post some code.Start with showing us where the panel that is getting in the way is instantiated and placed.Edit:Is that mainPanel?Message was edited by: dwg
dwga at 2007-7-12 17:25:43 > top of Java-index,Java Essentials,New To Java...
# 7

Hello,

Ok, here is the class that holds the GUI code. I removed the actionListeners as they aren't really relevant. The code is supposed to create a frame that holds a panel of buttons on the right, a panel of labels on the left, and a panel of chekboxes (16x16) in the middle. When a user choses start, the checkboxes are looped over and added to the track. I added a menu bar after the initial design and when I click on File it appears behind the panel holding the instrument names. I uploaded a better image now that I am off work (I am stationed in Afghanistan so my schedule is probably the opposite of most of yours).

http://kevineaton.net/problemMenu2.png

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

import javax.sound.midi.*;

import java.util.*;

import java.io.*;

public class BeatBox{

//Create the class variables, starting with GUI

JPanel mainPanel;

ArrayList<JCheckBox> checkBoxList;

Sequencer sequencer;

Sequence sequence;

Track track;

JFrame theFrame;

//Store the names of the instruments in an array

String[] instrumentNames = {"Bass Drum","Closed Hi-Hat","Open Hi-Hat","Acoustic Snare","Crash Cymbal","Hand Clap","High Tom","High Bongo","Maracas","Whistle","Low Conga","Cowbell","Vibraslap","Low-mid Tom","High Agogo","Open Hi Conga"};

//Store corresponding drum keys in another array

int[] instruments = {35,42,46,38,49,39,50,60,70,72,64,56,58,47,67,63};

//Main actually runs the program by calling the buildGUI method

public static void main(String[] args){

new BeatBox().buildGUI();

}

public void buildGUI(){

theFrame = new JFrame("BeatBox Version 1"); //Create the main frame for holding all of the components

theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//make sure it exits

BorderLayout layout = new BorderLayout();

JPanel background = new JPanel(layout); //the panel to hold the other panels

background.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));

//setup the menu and add the action listeners

JMenuBar menuBar = new JMenuBar();

JMenu fileMenu = new JMenu("File");

JMenuItem saveMenuItem = new JMenuItem("Save");

JMenuItem newMenuItem = new JMenuItem("New");

JMenuItem loadMenuItem = new JMenuItem("Load");

saveMenuItem.addActionListener(new SaveListener());

loadMenuItem.addActionListener(new LoadListener());

newMenuItem.addActionListener(new NewListener());

fileMenu.add(newMenuItem);

fileMenu.add(saveMenuItem);

fileMenu.add(loadMenuItem);

menuBar.add(fileMenu);

//prepare checkboxes for instruments

checkBoxList = new ArrayList<JCheckBox>();

JPanel buttonBox = new JPanel(); //create a panel to hold the buttons on the right

buttonBox.setLayout(new BoxLayout(buttonBox,BoxLayout.Y_AXIS));

//create buttons and assign listeners

JButton start = new JButton("Start");

start.addActionListener(new StartListener());

buttonBox.add(start);//Add the button to the box

JButton stop = new JButton("Stop");

stop.addActionListener(new StopListener());

buttonBox.add(stop);

JButton upTempo = new JButton("Tempo Up");

upTempo.addActionListener(new UpTempoListener());

buttonBox.add(upTempo);

JButton downTempo = new JButton("Tempo Down");

downTempo.addActionListener(new DownTempoListener());

buttonBox.add(downTempo);

JPanel nameBox = new JPanel(); //this panels hold the instrument names on the left

nameBox.setLayout(new BoxLayout(nameBox,BoxLayout.Y_AXIS));

for(int i = 0; i< 16; i++){

nameBox.add(new Label(instrumentNames[i]));

}

GridLayout grid = new GridLayout(16,16);

grid.setVgap(1);

grid.setHgap(2);

mainPanel = new JPanel(grid);//create a panel to hold checkboxes

//now add checkboxes to panel and arraylist

for(int i = 0; i< 256; i++){

JCheckBox c = new JCheckBox();

c.setSelected(false);

checkBoxList.add(c);

mainPanel.add(c);

}

background.add(BorderLayout.CENTER, mainPanel);//add panel to middle background

background.add(BorderLayout.EAST, buttonBox); //add the buttons on the right

background.add(BorderLayout.WEST, nameBox); //add the instrument names on the left

theFrame.getContentPane().add(background); //add the background panel to the frame

setupMidi(); //setup the sequencer and tracks

theFrame.setBounds(50,50,310,310);

theFrame.setJMenuBar(menuBar);//add menubar

theFrame.pack();

theFrame.setVisible(true);

}//exit buildGUI

Thanks for your help everyone!

LosingTheFighta at 2007-7-12 17:25:43 > top of Java-index,Java Essentials,New To Java...
# 8

Just change the following codes in your program.

OLD CODE

nameBox.setLayout(new BoxLayout(nameBox,BoxLayout.Y_AXIS));

for(int i = 0; i< 16; i++){

nameBox.add(new Label(instrumentNames[i]));

}

NEW CODE

nameBox.setLayout(new BoxLayout(nameBox,BoxLayout.Y_AXIS));

for(int i = 0; i< 16; i++){

nameBox.add(new JLabel(instrumentNames[i]));

}

Just change the Label to JLabel while adding;

Heavyweight components are always drawn in front of lightweight menus.

PremKumarUa at 2007-7-12 17:25:43 > top of Java-index,Java Essentials,New To Java...
# 9
Wow, I feel dumb. I thought I went through and made sure they were all lightweight components but I forgot the labels.Thanks again everyone for your help! As I get better with Java I hope to help others out as well.
LosingTheFighta at 2007-7-12 17:25:43 > top of Java-index,Java Essentials,New To Java...