Concepts / Creating Menus and Menu Items

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).

  • Programming

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?

  • The three menu names appear in a strip across the top of the window

  • Nothing appears, because the bar was never placed in the window

  • Only the first menu appears

Reveal answer
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.

java
Notes on the code
  • Line 1 creates the menu bar. JMenuBar has 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 JFrame named 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.

Main routineJMenuBarJMenuJFrame1. new JMenuBar()2. new JMenu, three times3. add(JMenu), three times4. setJMenuBar(menuBar)
In what order are the menu bar, the menus, and the frame involved, and which call attaches the finished bar to the window?

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.

JFrameContent paneDrawing canvasJMenuBarattached with setJMenuBarholdsset by setJMenuBarcontains
Is the JMenuBar a child of the content pane like other components, or does the frame hold it in its own separate place?

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

Definition

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.

JMenuBarmany menus, one call eachJMenuplaced by addJFrameholds one menu barJMenuBarassigned by setJMenuBaraddsetJMenuBar
How does placing a menu into a menu bar differ from attaching the menu bar to the frame, and why is one an add while the other is a set?
QuestionAdding a menu to a barAttaching the bar to a frame
Method usedadd(JMenu) on the JMenuBarsetJMenuBar(JMenuBar) on the JFrame
What is passed inOne JMenu per callOne JMenuBar
How many allowedSeveral menus, one add per menuOnly one menu bar per frame
Kind of operationAdd: contributes to the barSet: 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.

Worked example

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?

  1. 1
    Trace the creation

    The JMenuBar is created with new JMenuBar(). This is a valid single call, so the bar object exists.

  2. 2
    Trace the menu creation

    controlMenu, colorMenu, and toolsMenu are each created with new JMenu. The menus exist before they are placed.

  3. 3
    Trace the add calls

    menuBar.add(controlMenu), menuBar.add(colorMenu), and menuBar.add(toolsMenu) each place one menu into the same bar object. The bar now holds three menus.

  4. 4
    Trace 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.

  5. 5
    Locate 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.

Result

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 like
    menuBar.add(controlMenu); with no frame.setJMenuBar(menuBar) afterward
    Why it fails

    A 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 instead

    Call 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 like

    Menus are added to menuBarA, but frame.setJMenuBar(menuBarB) is called

    Why it fails

    The attached bar holds no menus, so the window shows an empty strip or nothing.

    Do this instead

    Use 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 fails

    A 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 instead

    Build 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

MEDIUM

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 JMenuBar is a container with no name and a no-parameter constructor. Menus are placed into it one at a time with add(JMenu).
  • The menu bar is a separate component of the JFrame and 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.