Creating Menus and Menu Items
A JMenuBar is a container for menus with no name and a no-parameter constructor; menus are placed in it with add(JMenu).
A Window With No Menu Strip
Imagine you run a drawing program. The window has a large content area full of drawing tools, but there is no menu strip along the top. The menus exist somewhere in your code, yet nothing appears on screen. This article follows the code that builds a menu strip and attaches it to a window, so you can see exactly where a menu setup can fail to show up.
What do you think happens?
You create a JMenuBar, add three JMenu objects to it, but never give the bar to the JFrame. What appears in the window?
Reveal answer
Nothing appears, because the bar was never placed in the window
A menu bar that is never placed in a window stays invisible. Creating the bar and adding menus to it is not enough. The bar must also be given to a window such as a JFrame, and that is the last step this article traces.
Tracing the MosaicDraw Build Steps
The example throughout this article is the MosaicDraw program, which uses three menus named controlMenu, colorMenu, and toolsMenu. Each menu is created first. The remaining work is to place those menus into a menu bar, and then to place that menu bar into a window. The source builds the bar with one creation statement followed by three add calls, and each statement does exactly one thing, which makes every step easy to check on its own.
- Line 1 creates the menu bar.
JMenuBarhas a no-parameter constructor, so this is a single call with no configuration. - Lines 2 to 4 create the three menus first, before they are placed anywhere.
- Lines 5 to 7 place each menu into the bar with
add(JMenu). Each call contributes one menu. - Line 8 gives the finished bar to the window. This assumes a
JFramenamed frame already exists.
Read the statements in order and notice the dependency. The bar must exist before menus can be added to it. The bar must be populated before it is attached in a meaningful way. Each call depends on the object created by the call before it. The sequence diagram below shows the same order as a timeline of messages between the main routine and the objects it creates.
Where the Menu Bar Sits in a Frame
Before reading the mechanism closely, decide for yourself where the menu bar belongs in a frame. You may already know the content pane from earlier window code, and you may be tempted to think the menu bar is one of the things that pane holds, just like buttons or a canvas. The source says otherwise: the menu bar is a separate component of the frame and is not contained inside the content pane.
This placement explains the symptom at the start of the article. The menus can exist in your code, and the content area can be full of drawing tools, yet the strip across the top stays empty. The menu bar lives in its own slot on the frame, so a menu bar that was never attached to the frame has no slot to appear in.
Why setJMenuBar Is a Set Operation
A JMenuBar is a container for menus. It has no name, and its constructor takes no parameters. Menus are placed in it with add(JMenu), and each call contributes one menu, whose name then appears in the bar. The bar itself is passive: it only stores what you add to it.
Attaching the bar to a window is a different kind of operation. The JFrame class provides an instance method for this purpose. The source writes it as setMenuBar(JMenuBar) in its prose, but in code it appears as setJMenuBar, so use that name when you write Java. Because a frame can hold only one menu bar, this is a set operation rather than an add operation. You assign the bar to the frame. You do not add another bar to a collection of bars.
| Question | Adding a menu to a bar | Attaching the bar to a frame |
|---|---|---|
| Method used | add(JMenu) on the JMenuBar | setJMenuBar(JMenuBar) on the JFrame |
| What is passed in | One JMenu per call | One JMenuBar |
| How many allowed | Several menus, one add per menu | Only one menu bar per frame |
| Kind of operation | Add: contributes to the bar | Set: assigns the bar to the frame |
Adding menus to a bar and attaching the bar to a frame are two separate steps.
Tracing a Menu Bar That Never Appears
When a menu does not appear, the cause is usually one of a few steps that were skipped or repeated. Each mistake leaves a different trace in the program, so you can find the failing step by asking which call was not made, or was made to the wrong object. The source suggests checking two things: whether the bar was attached to the frame, and whether the menus were added to that same bar object.
Finding the Missing Call in a Menu Setup
A developer runs the MosaicDraw window and sees no menu strip. The code creates a JMenuBar and three menus, and calls add three times. Which call is missing, and where should it go?
- 1Trace the creation
The
JMenuBaris created with newJMenuBar(). This is a valid single call, so the bar object exists. - 2Trace the menu creation
controlMenu,colorMenu, andtoolsMenuare each created with newJMenu. The menus exist before they are placed. - 3Trace the add calls
menuBar.add(controlMenu),menuBar.add(colorMenu), andmenuBar.add(toolsMenu)each place one menu into the same bar object. The bar now holds three menus. - 4Trace the attach call
The
frame.setJMenuBar(menuBar)call is absent. The bar was built correctly but never given to the frame, so the frame has no menu bar to display. - 5Locate the fix
Add
frame.setJMenuBar(menuBar)after the add calls and before the window is shown. The bar is now attached to the frame and the menus appear.
The missing call is setJMenuBar on the frame. The bar and its menus were built correctly, but the bar was never attached to the window.
Mistakes That Hide a Menu
The mistakes below share one pattern. Each leaves a call undone or sends it to the wrong object. Use the sequence and object diagrams above to decide which step is failing.
Common mistake Creating the menu bar and adding menus, but never calling setJMenuBar
What it looks likemenuBar.add(controlMenu); with no frame.setJMenuBar(menuBar) afterwardWhy it failsA menu bar that is never placed in a window stays invisible, so the menus never appear even though the code ran without errors.
Do this insteadCall frame.setJMenuBar(menuBar) to give the finished bar to the JFrame.
Common mistake Adding the menus to one bar object and attaching a different one
What it looks likeMenus are added to menuBarA, but frame.setJMenuBar(menuBarB) is called
Why it failsThe attached bar holds no menus, so the window shows an empty strip or nothing.
Do this insteadUse the same JMenuBar object for the add calls and for setJMenuBar.
Common mistake Treating setJMenuBar as an add operation and expecting several bars
Why it failsA frame holds only one menu bar, so the attach step is a set, not an add. Expecting several bars to stack on the frame misreads what the frame can hold.
Do this insteadBuild one bar, add all menus to it, and then set that single bar on the frame.
Common mistake Forgetting that menus must be created before they are added to the bar
Practice Tracing a Menu Setup
A developer writes the following setup for a window named frame. The window shows no menus. Trace the calls in order and identify the one step that causes the problem. Then state which object the attach call should receive.
JMenuBar bar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenu editMenu = new JMenu("Edit");
JMenuBar other = new JMenuBar();
bar.add(fileMenu);
bar.add(editMenu);
frame.setJMenuBar(other);Hints
- Ask which bar object received the add calls, and which bar object was passed to setJMenuBar.
- Remember that a menu bar's menus only appear if the bar holding them is the one attached to the frame.
Key Takeaways
- A
JMenuBaris a container with no name and a no-parameter constructor. Menus are placed into it one at a time withadd(JMenu). - The menu bar is a separate component of the
JFrameand is not contained inside the content pane, so it must be attached to the frame directly. - A frame holds only one menu bar, so attaching it with setJMenuBar is a set operation rather than an add operation.
- When a menu does not appear, trace the build-and-attach calls and confirm that the bar was attached to the frame and that the menus were added to that same bar object.