Creating Menus in Java

We started this chapter by introducing the most common components that you might want to place into a window, such as various kinds of buttons, text fields, and combo boxes. Swing also supports another type of user interface element—pull-down menus that are familiar from GUI applications.

A menu bar at the top of a window contains the names of the pull-down menus. Clicking on a name opens the menu containing menu items and submenus. When the user clicks on a menu item, all menus are closed and a message is sent to the program. Figure 11.17 shows a typical menu with a submenu.

1. Menu Building

Building menus is straightforward. First, create a menu bar:

var menuBar = new JMenuBar();

A menu bar is just a component that you can add anywhere you like. Normally, you want it to appear at the top of a frame. You can add it there with the setJMenuBar method:

frame.setJMenuBar(menuBar);

For each menu, you create a menu object:

var editMenu = new JMenu(“Edit”);

Add the top-level menus to the menu bar:

menuBar.add(editMenu);

Add menu items, separators, and submenus to the menu object:

var pasteItem = new JMenuItem(“Paste”);

editMenu.add(pasteItem);

editMenu.addSeparator();

JMenu optionsMenu = . . .; // a submenu

editMenu.add(optionsMenu);

You can see separators in Figure 11.17 below the Paste and Read-only menu items.

When the user selects a menu item, an action event is triggered. You need to install an action listener for each menu item:

ActionListener listener = . . .;

pasteItem.addActionListener(tistener);

The method JMenu.add(String s) conveniently adds a menu item to the end of a menu. For example:

editMenu.add(“Paste”);

The add method returns the created menu item, so you can capture it and add the listener, as follows:

JMenuItem pasteltem = editMenu.add(“Paste”);

pasteItem.addActionListener(listener);

It often happens that menu items trigger commands that can also be acti­vated through other user interface elements such as toolbar buttons. In Section 10.4.5, “Actions,” on p. 608, you saw how to specify commands through Action objects. You define a class that implements the Action interface, usually by extending the AbstractAction convenience class, specify the menu item label in the constructor of the AbstractAction object, and override the actionPerformed method to hold the menu action handler. For example:

var exitAction = new AbstractAction(“Exit”) // menu item text goes here

{

public void actionPerformed(ActionEvent event)

{

// action code goes here

System.exit(0);

}

};

You can then add the action to the menu:

JMenuItem exitItem = fileMenu.add(exitAction);

This command adds a menu item to the menu, using the action name. The action object becomes its listener. This is just a convenient shortcut for

var exitItem = new JMenuItem(exitAction);

fileMenu.add(exitItem);

2. Icons in Menu Items

Menu items are very similar to buttons. In fact, the JMenuItem class extends the AbstractButton class. Just like buttons, menus can have just a text label, just an icon, or both. You can specify the icon with the JMenuItem (St ring, Icon) or JMenuItem(Icon) constructor, or you can set it with the setIcon method that the JMenuItem class inherits from the AbstractButton class. Here is an example:

var cutItem = new JMenuItem(“Cut”, new ImageIcon(“cut.gif”));

In Figure 11.17, you can see icons next to several menu items. By default, the menu item text is placed to the right of the icon. If you prefer the text to be placed on the left, call the setHorizontalTextPosition method that the JMenuItem class inherits from the AbstractButton class. For example, the call

cutItem.setHorizontatTextPosition(SwingConstants.LEFT);

moves the menu item text to the left of the icon.

You can also add an icon to an action:

cutAction.putVatue(Action.SMALL_ICON, new ImageIcon(“cut.gif”));

Whenever you construct a menu item out of an action, the Action.NAME value becomes the text of the menu item and the Action.SMALL_ICON value becomes the icon.

Alternatively, you can set the icon in the AbstractAction constructor:

cutAction = new

AbstractAction(“Cut”, new ImageIcon(“cut.gif”))

{

public void actionPerformed(ActionEvent event)

{

}

};

3. Checkbox and Radio Button Menu Items

Checkbox and radio button menu items display a checkbox or radio button next to the name (see Figure 11.17). When the user selects the menu item, the item automatically toggles between checked and unchecked.

Apart from the button decoration, treat these menu items just as you would any others. For example, here is how you create a checkbox menu item:

var readonlyltem = new JCheckBoxMenuItem(“Read-only”);

optionsMenu.add(readonlyltem);

The radio button menu items work just like regular radio buttons. You must add them to a button group. When one of the buttons in a group is selected, all others are automatically deselected.

var group = new ButtonGroup();

var insertItem = new JRadioButtonMenuItem(“Insert”);

insertItem.setSelected(true);

var overtypeItem = new JRadioButtonMenuItem(“Overtype”);

group.add(insertItem);

group.add(overtypeItem);

optionsMenu.add(insertItem);

optionsMenu.add(overtypeItem);

With these menu items, you don’t necessarily want to be notified when the user selects the item. Instead, you can simply use the isSelected method to test the current state of the menu item. (Of course, that means you should keep a reference to the menu item stored in an instance field.) Use the setSelected method to set the state.

4. Pop-Up Menus

A pop-up menu is a menu that is not attached to a menu bar but floats somewhere (see Figure 11.18).

Create a pop-up menu just as you create a regular menu, except that a pop-up menu has no title.

var popup = new JPopupMenu();

Then, add your menu items as usual:

var item = new JMenuItem(“Cut”);

item.addActionListener(tistener);

popup.add(item);

Unlike the regular menu bar that is always shown at the top of the frame, you must explicitly display a pop-up menu by using the show method. Specify the parent component and the location of the pop-up, using the coordinate system of the parent. For example:

popup.show(panet, x, y);

Usually, you want to pop up a menu when the user clicks a particular mouse button—the so-called pop-up trigger. In Windows and Linux, the pop-up trigger is the nonprimary (usually, the right) mouse button. To pop up a menu when the user clicks on a component, using the pop-up trigger, simply call the method

component.setComponentPopupMenu(popup);

Very occasionally, you may place a component inside another component that has a pop-up menu. The child component can inherit the parent component’s pop-up menu by calling

chitd.setInheritsPopupMenu(true);

5. Keyboard Mnemonics and Accelerators

It is a real convenience for the experienced user to select menu items by keyboard mnemonics. You can create a keyboard mnemonic for a menu item by specifying a mnemonic letter in the menu item constructor:

var aboutItem = new JMenuItem(“About”, ‘A’);

The keyboard mnemonic is displayed automatically in the menu, with the mnemonic letter underlined (see Figure 11.19). For example, in the item defined in the last example, the label will be displayed as “About” with an underlined letter ‘A’. When the menu is displayed, the user just needs to press the A key, and the menu item is selected. (If the mnemonic letter is not part of the menu string, then typing it still selects the item, but the mnemonic is not displayed in the menu. Naturally, such invisible mnemonics are of dubious utility.)

Sometimes, you don’t want to underline the first letter of the menu item that matches the mnemonic. For example, if you have a mnemonic ‘A’ for the menu item “Save As,” then it makes more sense to underline the second ‘A’ (Save As). You can specify which character you want to have underlined by calling the setDisptayedMnemonicIndex method.

If you have an Action object, you can add the mnemonic as the value of the Action.MNEMONIC_KEY key, as follows:

aboutAction.putVatue(Action.MNEMONIC_KEY, new Integer(‘A’));

You can supply a mnemonic letter only in the constructor of a menu item, not in the constructor for a menu. To attach a mnemonic to a menu, call the setMnemonic method:

var hetpMenu = new JMenu(“Hetp”);

hetpMenu.setMnemonic(‘H’);

To select a top-level menu from the menu bar, press the Alt key together with the mnemonic letter. For example, press Alt+H to select the Help menu from the menu bar.

Keyboard mnemonics let you select a submenu or menu item from the cur­rently open menu. In contrast, accelerators are keyboard shortcuts that let you select menu items without ever opening a menu. For example, many programs attach the accelerators Ctrl+O and Ctrl+S to the Open and Save items in the File menu. Use the setAcceterator method to attach an accelerator key to a menu item. The setAcceterator method takes an object of type Keystroke. For example, the following call attaches the accelerator Ctrl+O to the openItem menu item:

openItem.setAcceterator(KeyStroke.getKeyStroke(“ctrt O”));

Typing the accelerator key combination automatically selects the menu option and fires an action event, as if the user had selected the menu option manually.

You can attach accelerators only to menu items, not to menus. Accelerator keys don’t actually open the menu. Instead, they directly fire the action event associated with a menu.

Conceptually, adding an accelerator to a menu item is similar to the technique of adding an accelerator to a Swing component. However, when the acceler­ator is added to a menu item, the key combination is automatically displayed in the menu (see Figure 11.20).

6. Enabling and Disabling Menu Items

Occasionally, a particular menu item should be selected only in certain con­texts. For example, when a document is opened in read-only mode, the Save menu item is not meaningful. Of course, we could remove the item from the menu with the JMenu.remove method, but users would react with some surprise to menus whose content keeps changing. Instead, it is better to deactivate the menu items that lead to temporarily inappropriate commands. A deacti­vated menu item is shown in gray and cannot be selected (see Figure 11.21).

To enable or disable a menu item, use the setEnabted method:

saveltem.setEnabted(fatse);

There are two strategies for enabling and disabling menu items. Each time circumstances change, you can call setEnabted on the relevant menu items or actions. For example, as soon as a document has been set to read-only mode, you can locate the Save and Save As menu items and disable them. Alterna­tively, you can disable items just before displaying the menu. To do this, you must register a listener for the “menu selected” event. The javax.swing.event package defines a MenuListener interface with three methods:

void menuSetected(MenuEvent event)

void menuDesetected(MenuEvent event)

void menuCanceted(MenuEvent event)

The menuSelected method is called before the menu is displayed. It can therefore be used to disable or enable menu items. The following code shows how to disable the Save and Save As actions whenever the Read Only checkbox menu item is selected:

public void menuSelected(MenuEvent event)

{

saveAction.setEnabled(!readonlyItem.isSelected());

saveAsAction.setEnabled(!readonlyItem.isSelected());

}

Listing 11.6 is a sample program that generates a set of menus. It shows all the features that you saw in this section: nested menus, disabled menu items, checkbox and radio button menu items, a pop-up menu, and keyboard mnemonics and accelerators.

7. Toolbars

A toolbar is a button bar that gives quick access to the most commonly used commands in a program (see Figure 11.22).

What makes toolbars special is that you can move them elsewhere. You can drag the toolbar to one of the four borders of the frame (see Figure 11.23). When you release the mouse button, the toolbar is dropped into the new location (see Figure 11.24).

The toolbar can even be completely detached from the frame. A detached toolbar is contained in its own frame (see Figure 11.25). When you close the frame containing a detached toolbar, the toolbar jumps back into the original frame.

Toolbars are straightforward to program. Add components into the toolbar:

var toolbar = new JTootBar();

toolbar.add(btueButton);

The JToolBar class also has a method to add an Action object. Simply populate the toolbar with Action objects, like this:

toolbar.add(blueAction);

The small icon of the action is displayed in the toolbar.

You can separate groups of buttons with a separator:

tootbar.addSeparator();

For example, the toolbar in Figure 11.22 has a separator between the third and fourth button.

Then, add the toolbar to the frame:

add(tootbar, BorderLayout.NORTH);

You can also specify a title for the toolbar that appears when the toolbar is undocked:

toolbar = new JToolBar(titleString);

By default, toolbars are initially horizontal. To have a toolbar start out vertical, use

toolbar = new JToolBar(SwingConstants.VERTICAL)

or

toolbar = new JToolBar(titleString, SwingConstants.VERTICAL)

Buttons are the most common components inside toolbars. But there is no restriction on the components that you can add to a toolbar. For example, you can add a combo box to a toolbar.

8. Tooltips

A disadvantage of toolbars is that users are often mystified by the meanings of the tiny icons in toolbars. To solve this problem, user interface designers invented tooltips. A tooltip is activated when the cursor rests for a moment over a button. The tooltip text is displayed inside a colored rectangle. When the user moves the mouse away, the tooltip disappears. (See Figure 11.26.)

In Swing, you can add tooltips to any J Component simply by calling the setToolTipText method:

exitButton.setToolTipText(“Exit”);

Alternatively, if you use Action objects, you associate the tooltip with the SHORT_DESCRIPTION key:

exitAction.putValue(Action.SHORT_DESCRIPTION, “Exit”);

Source: Horstmann Cay S. (2019), Core Java. Volume I – Fundamentals, Pearson; 11th edition.

Leave a Reply

Your email address will not be published. Required fields are marked *