Может ли JavaFX 8 установить строку меню по умолчанию?

#java #macos #javafx #javafx-8

#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 в com.apple.eawt API, но это не очень удобно, потому что:

  1. Установка строки меню оттуда зависает приложение (возможно, какая-то несовместимость между AWT и JavaFX — этого не происходит с тем же приложением, которое работает как чистый Swing.)
  2. Это требует от меня создания строки меню javafx для реальной Windows, но строки меню JMenuBar для строки меню по умолчанию, а JavaFX не позволяет мне повторно использовать мои классы действий, поэтому ужасные адаптеры в конечном итоге будут написаны для устранения разрыва.

Есть ли правильный способ установить это, который я просто еще не нашел? Я ожидал найти такой метод в приложении (некоторые сообщения в списке рассылки намекали, что он может оказаться там), но, похоже, он все еще отсутствует.

Комментарии:

1. Вы можете рассмотреть возможность создания запроса функции JavaFX .

Ответ №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();
  

Я не использую этот этап ни для чего. Она также должна быть невидимой. Раздражает и некрасиво, но это работает.

Другой печальный факт заключается в том, что я должен установить для любого окна одинаковую строку меню…. Это может работать или не работать для вас.

Ответ №2:

Вот еще одна возможность без каких-либо взломов сцены, но имейте в виду, что она использует частные API:

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

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

Важно: это решение только для OS X, поэтому вам все равно нужно добавить свое меню в сцену для других операционных систем.

Комментарии:

1. Он использует частные com.sun.javafx API, поэтому я предполагаю, что он официально не поддерживается, но, похоже, хорошо работает с OS X Oracle Java 8. Я связываю его с вызовом Platform.setImplicitExit(false); , чтобы остановить автоматическое завершение работы приложения при закрытии последнего окна.

Ответ №3:

Попробуйте использовать System.setProperty("apple.laf.useScreenMenuBar", "true");

для получения дополнительной информации см.:

https://developer.apple.com/library/mac/documentation/java/Reference/Java_PropertiesRef/Articles/JavaSystemProperties.html

и

https://developer.apple.com/library/mac/documentation/java/Conceptual/Java14Development/00-Intro/JavaDevelopment.html

Надеюсь, это поможет!

Комментарии:

1. Это работает для AWT / Swing, но не для JavaFX, который не основан на AWT.