5

So I've looked around a fair bit, but I've not been able to find any information on how to make an application menu in JavaFX.

I've seen a project 'Jayatana' which seems to allow applications to have proper application menus in Ubuntu using Intellij at least (as an example).

I've also seen a few suggestions that using something like the following will work for OS X users:-

final List<MenuBase> menus = new ArrayList<>();
menus.add(GlobalMenuAdapter.adapt(menu));
Toolkit.getToolkit().getSystemMenu().setMenus(menus);

And there is also the NSMenuFX project, again for OS X.

And I've also seen the java-gnome project which I think only works for Swing.

But what I'd really like is some way of making application menus, preferably in a non-OS specific manner.

I'm happy to use a third party jar or whatever which does the heavy lifting but really, does anything like this exist?

At this point would my best bet be using Swing to create the shell of the JavaFX application and use methods which will integrate application menus with Swing instead? If that's the case, is there something that can do this automatically from JavaFX and handle the switching of the differing implementations?

edit

In the end, I simply used a combination of both Swing and JavaFX. I put the JavaFX app inside which allowed me to use the application menus which already work in Swing.

Not ideal, but it did work.

1
  • 1
    As of Java 9, the java.awt.Desktop class has added methods to partially support a true application menu, such as setPreferencesHandler and setAboutHandler.
    – VGR
    Commented Nov 28, 2017 at 21:44

2 Answers 2

3

I think you are just looking for MenuBar.useSystemMenuBarProperty(). If you call this method on a menu bar, then if the platform supports system menus (e.g. OS X) the menu will not appear in the scene graph but will be used as the system menu.

SSCCE:

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.stage.Stage;

public class SystemMenuExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        MenuBar menuBar = new MenuBar();
        Menu menu = new Menu("File");
        MenuItem quit = new MenuItem("Quit");
        quit.setOnAction(e -> Platform.exit());
        menu.getItems().add(quit);
        menuBar.getMenus().add(menu);
        menuBar.setUseSystemMenuBar(true);

        BorderPane root = new BorderPane();
        root.setTop(menuBar);
        Scene scene = new Scene(root, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
2

The solution provided by James_D is the standard way of dealing with this in JavaFX but this solution does not work on the Mac, e.g., if you plan to internationalize your application. The Mac introduces some default menu items which you cannot properly deal with that way. That's where the NSMenuFX project comes into play.

NSMenuFX helps you to

Customize the auto-generated application menu of your JavaFX app
Automatically use the same menu bar for all stages
Create common OS X menus like the Window menu

If you can live with the deficiencies of the JavaFX solution use it, if not have a look at NSMenuFX or any of the other projects mentioned for Linux.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.