JavaFX Tutorial - JavaFX Menu








Menus are a standard way for desktop applications to select options.

Menus and menu items can have key combinations to select options, known as keyboard shortcuts.

Creating Menus and Menu Items

We must create a menu bar javafx.scene.control.MenuBar object to hold javafx.scene.control.Menu objects.

Menu objects can contain Menu and javafx.scene.control.MenuItem objects. A menu may contain other menus as submenus. MenuItems are child options within a Menu object.

The following code shows how to create a Menu Bar and add menu and menu items.

Menu class is a subclass of MenuItem, it has a getItems().add() method that's capable of adding children such as other Menu and MenuItem instances.

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.RadioMenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
//from   ww w .  ja va 2  s  .c o  m
public class Main extends Application {

  @Override
  public void start(Stage primaryStage) {
    BorderPane root = new BorderPane();
    Scene scene = new Scene(root, 300, 250, Color.WHITE);

    MenuBar menuBar = new MenuBar();
    menuBar.prefWidthProperty().bind(primaryStage.widthProperty());
    root.setTop(menuBar);

    // File menu - new, save, exit
    Menu fileMenu = new Menu("File");
    MenuItem newMenuItem = new MenuItem("New");
    MenuItem saveMenuItem = new MenuItem("Save");
    MenuItem exitMenuItem = new MenuItem("Exit");
    exitMenuItem.setOnAction(actionEvent -> Platform.exit());

    fileMenu.getItems().addAll(newMenuItem, saveMenuItem,
        new SeparatorMenuItem(), exitMenuItem);

    Menu webMenu = new Menu("Web");
    CheckMenuItem htmlMenuItem = new CheckMenuItem("HTML");
    htmlMenuItem.setSelected(true);
    webMenu.getItems().add(htmlMenuItem);

    CheckMenuItem cssMenuItem = new CheckMenuItem("CSS");
    cssMenuItem.setSelected(true);
    webMenu.getItems().add(cssMenuItem);

    Menu sqlMenu = new Menu("SQL");
    ToggleGroup tGroup = new ToggleGroup();
    RadioMenuItem mysqlItem = new RadioMenuItem("MySQL");
    mysqlItem.setToggleGroup(tGroup);

    RadioMenuItem oracleItem = new RadioMenuItem("Oracle");
    oracleItem.setToggleGroup(tGroup);
    oracleItem.setSelected(true);

    sqlMenu.getItems().addAll(mysqlItem, oracleItem,
        new SeparatorMenuItem());

    Menu tutorialManeu = new Menu("Tutorial");
    tutorialManeu.getItems().addAll(
        new CheckMenuItem("Java"),
        new CheckMenuItem("JavaFX"),
        new CheckMenuItem("Swing"));

    sqlMenu.getItems().add(tutorialManeu);

    menuBar.getMenus().addAll(fileMenu, webMenu, sqlMenu);

    primaryStage.setScene(scene);
    primaryStage.show();
  }
  public static void main(String[] args) {
    launch(args);
  }
}

The code above generates the following result.

null




Special Menu Items

To add checked options or radio buttons to a Menu, we can use the following subclasses of the MenuItem class.

The following listing shows the available MenuItem subclasses to use as menu options.

  • javafx.scene.control.CheckMenuItem
  • javafx.scene.control.RadioMenuItem
  • javafx.scene.control.CustomMenuItem
  • javafx.scene.control.SeparatorMenuItem
  • javafx.scene.control.Menu

A CheckMenuItem menu item is similar to a CheckBox control, allowing the user to select items.

The RadioMenuItem menu item is similar to the RadioButton control, allowing the user to select only one item from an item group.

To create a custom menu item, we can use the CustomMenuItem class.

SeparatorMenuItem is a derived class of type CustomMenuItem and displays a visual line to separate menu items.

Using CustomMenuItem to add Slider to MenuItem

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.CustomMenuItem;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.Slider;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/* w w w . j  a v a2  s .  c  o m*/
public class Main extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Menus");
        Group root = new Group();
        Scene scene = new Scene(root, 300, 250, Color.WHITE);
        
        MenuBar menuBar = new MenuBar();
        
        Menu menu = new Menu("File");
        menu.getItems().add(new MenuItem("New"));
        menu.getItems().add(new MenuItem("Save"));
        menu.getItems().add(new SeparatorMenuItem());
        menu.getItems().add(new MenuItem("Exit"));

        CustomMenuItem customMenuItem = new CustomMenuItem(new Slider());
        customMenuItem.setHideOnClick(false);
        menu.getItems().add(customMenuItem);
        
        menuBar.getMenus().add(menu);
        
        menuBar.prefWidthProperty().bind(primaryStage.widthProperty());
        
        root.getChildren().add(menuBar); 
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

The code above generates the following result.

null




To add event handler to menu item we can use setOnAction() method, which receives a functional interface of type EventHandler<ActionEvent>, which is the handler code that is invoked when the menu item is selected.

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/*from   w w w.  j a  v a  2  s . com*/
public class Main extends Application {

  @Override
  public void start(Stage primaryStage) {
    BorderPane root = new BorderPane();
    Scene scene = new Scene(root, 300, 250, Color.WHITE);

    MenuBar menuBar = new MenuBar();
    menuBar.prefWidthProperty().bind(primaryStage.widthProperty());
    root.setTop(menuBar);

    Menu fileMenu = new Menu("File");
    MenuItem exitMenuItem = new MenuItem("Exit");
    fileMenu.getItems().add(exitMenuItem);
    exitMenuItem.setOnAction(actionEvent -> Platform.exit());

    menuBar.getMenus().addAll(fileMenu);

    primaryStage.setScene(scene);
    primaryStage.show();
  }
  public static void main(String[] args) {
    launch(args);
  }
}

The code above generates the following result.

null

Key Mnemonics

Standard menus generally have keyboard mnemonics to select menu items without using a mouse.

The user can hit the Alt key and the letter with an underscore _ to activate a menu and then navigate with arrow keys.

To add key mnemonics to a menu, we call the constructor with a String value and place an underscore character preceding the chosen letter in the menu or menu item's text.

We then pass true to the setMnemonicParsing(true) method.

The following code creates a File menu that uses the letter "F" as the mnemonic.

Menu fileMenu = new Menu("_File");
fileMenu.setMnemonicParsing(true);

Full source code

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
//  w  w w  .  j a  v a 2 s  .  com
public class Main extends Application {

  @Override
  public void start(Stage primaryStage) {
    BorderPane root = new BorderPane();
    Scene scene = new Scene(root, 300, 250, Color.WHITE);

    MenuBar menuBar = new MenuBar();
    menuBar.prefWidthProperty().bind(primaryStage.widthProperty());
    root.setTop(menuBar);

    Menu fileMenu = new Menu("_File");
    fileMenu.setMnemonicParsing(true);
    MenuItem exitMenuItem = new MenuItem("Exit");
    fileMenu.getItems().add(exitMenuItem);
    exitMenuItem.setOnAction(actionEvent -> Platform.exit());

    menuBar.getMenus().addAll(fileMenu);

    primaryStage.setScene(scene);
    primaryStage.show();
  }
  public static void main(String[] args) {
    launch(args);
  }
}

The code above generates the following result.

null

Key Combinations

A key combination is a combination of keystrokes to select a menu option. The key combinations are referred as keyboard shortcuts.

For example, on the Windows platform the key combination of Ctrl + S can save a file. On the Mac OS platform, the key combination would be Command + S.

Keys such as Ctrl, Command, Alt, Shift, and Meta are called modifier keys.

Usually the modifiers are pressed in combination with a single letter.

To create a key combination, use KeyCodeCombination object and passin the keystroke and the modifiers.

The following code creates a key code combination of (Ctrl or Meta) + S.


MenuItem saveItem = new MenuItem("_Save");
saveItem.setMnemonicParsing(true);
saveItem.setAccelerator(new KeyCodeCombination(KeyCode.S, KeyCombination.SHORTCUT_DOWN));

The code uses the KeyCombination.SHORTCUT_DOWN value as the key modifier instead of CONTROL_DOWN or META_DOWN. The value of SHORTCUT_DOWN will enable the application to be cross-platform.

The values CONTROL_DOWN and META_DOWN are system dependent on the Windows and MacOS platforms respectively, but SHORTCUT_DOWN works on all platforms.

Context Menus

Context menus are popup menus displayed when a user right-clicks the mouse button.

To create a context menu, use ContextMenu class. The ContextMenu menu has a getItems().add() method to add menu items.

The following code shows a context menu instantiated with a menu item (exitItem):

ContextMenu  contextFileMenu = new ContextMenu(exitItem);

To respond to a mouse right-click, add an event handler to listen for a right-click event and call the context menu's show() method.

The following code sets up an event handler to show and hide a context menu based on a right or left mouse click, respectively.

The hide() method is invoked by the primary mouse click (left-click) to remove the context menu.

primaryStage.addEventHandler(MouseEvent.MOUSE_CLICKED,  (MouseEvent  me) ->  {
    if (me.getButton() == MouseButton.SECONDARY  || me.isControlDown())  {
        contextFileMenu.show(root, me.getScreenX(), me.getScreenY());
    }  else  {
        contextFileMenu.hide();
    }
});