Building Menu in JavaFX
Posted: under JavaFX Technology.
Tags: javafx, menu, swing, tips
The JavaFX APIs do not come with a menu GUI component. Perhaps the JavaFX team in Sun does not think it is an important thing in RIA. However, from time to time, developers are asking questions on how to build a menu bar from JavaFX. So I decided to write an example of the menu bar in JavaFX.
JavaFX provides us a class javafx.ext.swing.SwingComponent, which can wrap a SWING component into a JavaFX node. We know that we can build complicated menus in SWING. Therefore, we can wrap up the SWING menu items and put them into a JavaFX Stage. Let’s take a look at the below code:
/*
* Main.fx
* @author Henry Zhang http://www.javafxgame.com
*/
package menutest;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
import java.awt.event.*;
import javax.swing.*;
import javafx.ext.swing.SwingComponent;
var w : Number = 480 on replace { fxMenuBar.width = w ; } ;
var h = 300;
var selected = "";
var handler = ActionListener {
public override function actionPerformed( e: ActionEvent ) {
selected = e.getActionCommand() ;
}
};
var menuBar = new JMenuBar();
var menu = new JMenu("Menu A");
menu.setMnemonic(KeyEvent.VK_A);
menuBar.add(menu);
var menuItem = new JMenuItem("Item A-1");
menuItem.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
menuItem.addActionListener(handler);
menu.add(menuItem);
menuItem = new JMenuItem("Item A-2");
menuItem.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_2, ActionEvent.ALT_MASK));
menuItem.addActionListener(handler);
menu.add(menuItem);
menu = new JMenu("Menu B");
menu.setMnemonic(KeyEvent.VK_B);
menuBar.add(menu);
menuItem = new JMenuItem("Item B-1");
menuItem.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_3, ActionEvent.ALT_MASK));
menuItem.addActionListener(handler);
menu.add(menuItem);
menuItem = new JMenuItem("Item B-2");
menuItem.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_4, ActionEvent.ALT_MASK));
menuItem.addActionListener(handler);
menu.add(menuItem);
var fxMenuBar : SwingComponent = SwingComponent.wrap(menuBar);
fxMenuBar.width = w;
fxMenuBar.layoutX=0;
fxMenuBar.layoutY=0;
Stage {
title: "JavaFX Menu Test"
width: bind w with inverse
height: h
scene: Scene {
content: [
fxMenuBar,
Text {
font : Font {
size : 16
}
translateX: 50
translateY: 100
x: 10
y: 30
content: bind if ( selected == "" ) "Ready"
else "Menu clicked: {selected}"
}
]
}
}
In the code, we first constructed a menu bar with two menus. Each menu contained two menu items. This is the standard way in SWING to show a menu bar. The line below created a SwingComponent instance which acted as a wrapper of the SWING menu bar:
var fxMenuBar : SwingComponent = SwingComponent.wrap(menuBar);
The below 3 lines were used to keep the menu bar on the top of the window(Stage).
fxMenuBar.width = w; fxMenuBar.layoutX=0; fxMenuBar.layoutY=0;
In the Stage class, we can see that fxMenuBar was used like a normal JavaFX node. Since the window is resizable, we need to adjust the width of the menu bar so that it changes with the window. A trigger has been added on the variable w to adjust the width of the menu bar.
var w : Number = 480 on replace { fxMenuBar.width = w ; };
The actual binding to the window’s width was achieved by this statement:
Stage {
...
width: bind w with inverse
...
}
Below is a screenshot of the program. You can use accelerators like Alt+1,2,3,4 to activate the menu items.

Related Articles:
JavaFX Scene Displayed in a Swing JFrame Window
Calling JavaFX Classes from Java Code
Comments (2)
Jul 27 2009