JavaFX 8可以设置默认菜单栏吗?

时间:2014-06-27 12:46:26

标签: java macos javafx javafx-8

带有屏幕菜单栏的简单玩具应用程序可以像这样在Java FX 8中编写:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {
    public static void main(final String[] args) throws Exception {
        launch(Main.class, args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        MenuBar menuBar = new MenuBar();
        Menu fileMenu = new Menu("File");
        MenuItem newNotebookMenuItem = new MenuItem("New Notebook...");
        newNotebookMenuItem.setAccelerator(KeyCombination.keyCombination("Meta+N"));
        newNotebookMenuItem.setOnAction(event -> { System.out.println("Action fired"); });
        fileMenu.getItems().add(newNotebookMenuItem);
        menuBar.getMenus().add(fileMenu);
        menuBar.setUseSystemMenuBar(true);

        VBox root = new VBox();
        root.getChildren().add(menuBar);
        Scene scene = new Scene(root, 400, 350);
        stage.setScene(scene);
        stage.show();
    }
}

这可能适合制作计算器应用程序,例如只有一个窗口的应用程序,当最后一个窗口关闭时应用程序关闭,但我的应用程序是基于文档的。当基于文档的应用程序没有打开文档时,没有打开窗口,但菜单应保持可见,以便用户可以打开新文档。

执行此操作的常用方法是setDefaultMenuBar API中的com.apple.eawt,但这并不是很好,因为:

  1. 从那里设置菜单栏会挂起应用程序(可能是AWT和JavaFX之间的某种不兼容性 - 它与使用纯Swing运行的应用程序不会发生。)
  2. 它要求我为真实窗口构建一个javafx MenuBar,但是默认菜单栏的JMenuBar和JavaFX不允许我重用我的Action类,因此糟糕的适配器最终会被编写以弥补差距。
  3. 有没有正确的方法设置这个我还没找到呢?我希望在应用程序上找到这样一种方法(一些邮件列表帖子暗示它可能会在那里结束)但看起来它仍然缺失。

3 个答案:

答案 0 :(得分:1)

目前我的诀窍如下:

Pane pane = new Pane();
pane.maxWidth(1);
pane.maxHeight(1);
pane.resize(1, 1);
pane.getChildren().add(menuBar);
Scene scene = new Scene(pane,1,1);
scene.setFill(null);
primaryStage.initStyle(StageStyle.TRANSPARENT);
primaryStage.setWidth(1);
primaryStage.setHeight(1);
primaryStage.setScene(scene);
primaryStage.show();

我不会把这个阶段用于任何事情。它也应该看起来不可见。恼人的&丑陋,但它确实有效。

另一个令人遗憾的事实是,我必须设置任何窗口以拥有相同的菜单栏......这可能适用于您,也可能不适合您。

答案 1 :(得分:1)

这是另一种没有任何场景黑客的可能性,但要注意它使用私有API:

List<MenuBase> menus = new ArrayList<>();
menus.add(GlobalMenuAdapter.adapt(fileMenu));

Toolkit.getToolkit().getSystemMenu().setMenus(menus);

重要事项:这是仅限OS X的解决方案,因此您仍需要将菜单添加到其他操作系统的场景中。

答案 2 :(得分:-1)