Pure Java JavaFX 2.0 Menus
I list the entire code listing for this example later in this post, but I first show snippets of the code to make it easier to focus on each piece. A good starting point for using JavaFX 2.0 menus is to instantiate an instance of MenuBar. This is straightforward as shown next.
Instantiating a javafx.scene.control.MenuBar
1 | final MenuBar menuBar = new MenuBar(); |
A MenuBar
can contain Menu instances as its children and each Menu
instance can have instances of MenuItem as its children. The next code listing demonstrates instantiation of a Menu
, adding of MenuItem
instances (or an instance of SeparatorMenuItem) to that Menu
instance, and then adding the Menu
instance to the instance of MenuBar
.
Adding Newly Instantiated Menu and MenuItem Instances to MenuBar
1 2 3 4 5 6 7 8 9 | // Prepare left-most 'File' drop-down menu final Menu fileMenu = new Menu( 'File' ); fileMenu.getItems().add( new MenuItem( 'New' )); fileMenu.getItems().add( new MenuItem( 'Open' )); fileMenu.getItems().add( new MenuItem( 'Save' )); fileMenu.getItems().add( new MenuItem( 'Save As' )); fileMenu.getItems().add( new SeparatorMenuItem()); fileMenu.getItems().add( new MenuItem( 'Exit' )); menuBar.getMenus().add(fileMenu); |
The example above is too simplified for realistic uses. There are no event handlers or actions associated with clicking on any of the menu items and there are no ways to select the menu items via keystroke rather than via mouse clicking. The next code listing demonstrates instantiation of MenuItem
instances that include more than just a text string. In this code listing, there is an example of using MenuItemBuilder to build a much more complex MenuItem
that includes association to a key combination and includes an association to an action handler.
More Sophisticated MenuItem Instantiation with Keystroke and Event Associations
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | // Prepare 'Help' drop-down menu final Menu helpMenu = new Menu( 'Help' ); final MenuItem searchMenuItem = new MenuItem( 'Search' ); searchMenuItem.setDisable( true ); helpMenu.getItems().add(searchMenuItem); final MenuItem onlineManualMenuItem = new MenuItem( 'Online Manual' ); onlineManualMenuItem.setVisible( false ); helpMenu.getItems().add(onlineManualMenuItem); helpMenu.getItems().add( new SeparatorMenuItem()); final MenuItem aboutMenuItem = MenuItemBuilder.create() .text( 'About' ) .onAction( new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { out.println( 'You clicked on About!' ); } }) .accelerator( new KeyCodeCombination( KeyCode.A, KeyCombination.CONTROL_DOWN)) .build(); helpMenu.getItems().add(aboutMenuItem); menuBar.getMenus().add(helpMenu); |
Besides demonstrating MenuItemBuilder
, associating a key combination (CTRL-A in this case) with a menu item, and associating an action with a menu item, this code example also demonstrates making a menu item disabled (grayed out) with setDisable(boolean) or making it not appear at all with setVisible(boolean). Although I could have specified disabling the menu item or making the menu item invisible with a MenuItemBuilder
, I intentionally used ‘set’ methods on the MenuItem
s in this example to contrast that approach with using the MenuItemBuilder
.
For completeness, here is the entire code listing of my example.
JavaFxMenus.java (The Complete Listing)
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 | package dustin.examples; import static java.lang.System.out; import javafx.application.Application; import javafx.beans.property.ReadOnlyDoubleProperty; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyCombination; import javafx.scene.paint.Color; import javafx.stage.Stage; /** * Example of creating menus in JavaFX. * * @author Dustin */ public class JavaFxMenus extends Application { /** * Build menu bar with included menus for this demonstration. * * @param menuWidthProperty Width to be bound to menu bar width. * @return Menu Bar with menus included. */ private MenuBar buildMenuBarWithMenus( final ReadOnlyDoubleProperty menuWidthProperty) { final MenuBar menuBar = new MenuBar(); // Prepare left-most 'File' drop-down menu final Menu fileMenu = new Menu( 'File' ); fileMenu.getItems().add( new MenuItem( 'New' )); fileMenu.getItems().add( new MenuItem( 'Open' )); fileMenu.getItems().add( new MenuItem( 'Save' )); fileMenu.getItems().add( new MenuItem( 'Save As' )); fileMenu.getItems().add( new SeparatorMenuItem()); fileMenu.getItems().add( new MenuItem( 'Exit' )); menuBar.getMenus().add(fileMenu); // Prepare 'Examples' drop-down menu final Menu examplesMenu = new Menu( 'JavaFX 2.0 Examples' ); examplesMenu.getItems().add( new MenuItem( 'Text Example' )); examplesMenu.getItems().add( new MenuItem( 'Objects Example' )); examplesMenu.getItems().add( new MenuItem( 'Animation Example' )); menuBar.getMenus().add(examplesMenu); // Prepare 'Help' drop-down menu final Menu helpMenu = new Menu( 'Help' ); final MenuItem searchMenuItem = new MenuItem( 'Search' ); searchMenuItem.setDisable( true ); helpMenu.getItems().add(searchMenuItem); final MenuItem onlineManualMenuItem = new MenuItem( 'Online Manual' ); onlineManualMenuItem.setVisible( false ); helpMenu.getItems().add(onlineManualMenuItem); helpMenu.getItems().add( new SeparatorMenuItem()); final MenuItem aboutMenuItem = MenuItemBuilder.create() .text( 'About' ) .onAction( new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { out.println( 'You clicked on About!' ); } }) .accelerator( new KeyCodeCombination( KeyCode.A, KeyCombination.CONTROL_DOWN)) .build(); helpMenu.getItems().add(aboutMenuItem); menuBar.getMenus().add(helpMenu); // bind width of menu bar to width of associated stage menuBar.prefWidthProperty().bind(menuWidthProperty); return menuBar; } /** * Start of JavaFX application demonstrating menu support. * * @param stage Primary stage. */ @Override public void start( final Stage stage) { stage.setTitle( 'Creating Menus with JavaFX 2.0' ); final Group rootGroup = new Group(); final Scene scene = new Scene(rootGroup, 800 , 400 , Color.WHEAT); final MenuBar menuBar = buildMenuBarWithMenus(stage.widthProperty()); rootGroup.getChildren().add(menuBar); stage.setScene(scene); stage.show(); } /** * Main executable function for running examples. * * @param arguments Command-line arguments: none expected. */ public static void main( final String[] arguments) { Application.launch(arguments); } } |
The next series of screen snapshots attempt to demonstrate what this application looks like when executed using the java
launcher. The images show the initial appearance of the application, the drop-down menu presented when ‘File’ menu is clicked on, the drop-down menu presented when the ‘Help’ menu is clicked on, and finally an image that shows the message written to standard output when the ‘About’ menu item is clicked on under the ‘Help’ menu.
The code in the example featured in this post has numerous syntax features that should look familiar to Swing developers. In fact, many of the JavaFX classes used above have the same names as AWT classes and so care must be used to import the correct class when using the IDE’s automatic import suggestions.
The example above also provides an example of JavaFX binding. In particular, the width of the menu bar is bound to the width of the stage’s width. This is useful because it looks better to have the menu bar span the entire top of the visual rather than being just wide enough to hold the menu labels.
Building menus is fairly straightforward in JavaFX 2.0 and can be implemented using basic Java tools and the JavaFX 2.0 JAR.
Happy coding and don’t forget to share!
Reference: (Pure Java) JavaFX 2.0 Menus from our JCG partner Dustin Marx at the Inspired by Actual Events blog.