{{ !articles[0].partner.isSponsoringArticle ? "Platinum" : "Portal" }} Partner

How to Integrate JavaFX into the NetBeans Platform Menubar

Let's say you want to replace the NetBeans Platform menubar, written in Swing, with one written in JavaFX. Why? For fun. Also, CSS stylesheet support in JavaFX is handy for redesigning the menubar's appearance: 

The coloring in the menubar above, which is indeed a JavaFX MenuBar, is as follows:

/*Menu Bar*/
.menu-bar {
    -fx-background-color: orange;

.menu .label {
    -fx-text-fill: black;

/*Menu Items*/
.menu-item:focused {
    -fx-background-color: greenyellow;
.menu-item .label {
    -fx-text-fill: black;

Here's some references relevant to this task:

And here's the steps, all based on the links above:

  1. Remove the default menubar and replace with your own:
    package org.demo.menu;
    import org.openide.modules.OnStart;
    public class Installer implements Runnable {
        public void run() {
            System.setProperty("netbeans.winsys.menu_bar.path", "LookAndFeel/MenuBar.instance");
  2. In the layer, i.e., as referred to in the folder location above, define your Swing menubar:
    <folder name="LookAndFeel">
        <file name="MenuBar.instance">
            <attr name="instanceOf" stringvalue="org.openide.awt.MenuBar"/>
            <attr name="instanceCreate" newvalue="org.demo.menu.MyMenuBar"/>
  3. Now create the class that you defined above. Start by putting a JFXPanel into the Swing menubar. Then you're good to go. Just add the MenuBar, Menus, and MenuItems from JavaFX, based on what you find in the relevant folders in the application's filesystem.
    public class MyMenuBar extends JMenuBar {
        public MyMenuBar() {
            final JFXPanel menuFxPanel = new JFXPanel();
            Platform.runLater(new Runnable() {
                public void run() {
                    Scene scene = new Scene(new VBox(), 400, 20);
                    MenuBar menuBar = new MenuBar();
                    FileObject menuFolder = FileUtil.getConfigFile("Menu");
                    FileObject[] menuKids = menuFolder.getChildren();
                    for (FileObject menuKid : FileUtil.getOrder(Arrays.asList(menuKids), true)) {
                        Menu newMenuFromFileObject = new Menu(menuKid.getName());
                        builtMenuStructure(menuKid, newMenuFromFileObject);
                    ((VBox) scene.getRoot()).getChildren().addAll(menuBar);
        private void builtMenuStructure(FileObject fo, Menu menu) {
            DataFolder df = DataFolder.findFolder(fo);
            DataObject[] childs = df.getChildren();
            for (DataObject oneChild : childs) {
                if (oneChild.getPrimaryFile().isFolder()) {
                    FileObject childFo = oneChild.getPrimaryFile();
                    Menu newMenu = new Menu(childFo.getName());
                    builtMenuStructure(childFo, newMenu);
                } else {
                    Object instanceObj = FileUtil.getConfigObject(
                    if (instanceObj instanceof JSeparator) {
                        menu.getItems().add(new SeparatorMenuItem());
                    } else if (instanceObj instanceof Action) {
                        final Action a = (Action) instanceObj;
                        String name = (String) a.getValue(Action.NAME);
                        String cutAmpersand = Actions.cutAmpersand(name);
                        MenuItem menuItem = new MenuItem(cutAmpersand);
                        menuItem.setOnAction(new EventHandler<ActionEvent>() {
                            public void handle(final ActionEvent t) {
                                try {
                                    SwingUtilities.invokeAndWait(new Runnable() {
                                        public void run() {
                                            java.awt.event.ActionEvent event =
                                                    new java.awt.event.ActionEvent(
                                } catch (InterruptedException ex) {
                                } catch (InvocationTargetException ex) {

That's all and you're done. Congratulations, you've replaced the default Swing menubar in the NetBeans Platform with a new one defined in JavaFX.

Maybe handy to know what the import statement in the above class are:

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.layout.VBox;
import javax.swing.Action;
import javax.swing.JMenuBar;
import javax.swing.JSeparator;
import javax.swing.SwingUtilities;
import org.openide.awt.Actions;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataFolder;
import org.openide.loaders.DataObject;
import org.openide.util.Exceptions;
{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks