<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">I’ve been thinking about this some more, and I really didn’t like the idea of adding a new method to the Application class for each application menu thing we wanted to support. I think it is much better to add a new, final ApplicationMenu class to javafx.application.<div><br></div><div>I have also added what I think is support for GTK applications, but I cannot test this because I only have an M1 Mac Mini. Is anyone with a Linux box interested in testing this? Code is at <a href="https://github.com/dkkopp/jfx/tree/appmenu">https://github.com/dkkopp/jfx/tree/appmenu</a><br><div><br></div><div>So, here is take 2:</div><div><br></div><div>Added to ConditionalFeature:</div><div><br></div><div><div><br></div><div>    /**</div><div>     * Indicates whether or not an application menu exists.</div><div>     *</div><div>     * @since JavaFX 24.0</div><div>     */</div><div>    APPLICATION_MENU</div><div><br></div></div><div>And in PlatformImpl:</div><div><br></div><div><div>            case APPLICATION_MENU:</div><div>                return PlatformUtil.isMac() || PlatformUtil.isLinux();</div></div><div><br></div><div><br></div><div>Added to javafx.application.Application:</div><div><br></div><div><div>    private ApplicationMenu applicationMenu = null;</div><div><br></div><div>    /**</div><div>     * Gets the ApplicationMenu for this application on platforms which support this concept.</div><div>     *</div><div>     * @return the ApplicationMenu</div><div>     *</div><div>     * @throws java.lang.UnsupportedOperationException if the current platform does not support the</div><div>     * ConditionalFeature.APPLICATION_MENU feature</div><div>     */</div><div>    public final ApplicationMenu getApplicationMenu() {</div><div>        if (!PlatformImpl.isSupported(ConditionalFeature.APPLICATION_MENU)) {</div><div>            throw new UnsupportedOperationException("ConditionalFeature.APPLICATION_MENU is not"</div><div>                    + " supported on this platform");</div><div>        }</div><div><br></div><div>        synchronized (this) {</div><div>            if (applicationMenu == null) {</div><div>                applicationMenu = new ApplicationMenu();</div><div>            }</div><div>            return applicationMenu;</div><div>        }</div><div>    }</div><div><br></div></div><div>New class added to package javafx.application:</div><div><br></div><div><div>/**</div><div> * This class provides application menu integration for an Application on platforms which support</div><div> * this concept.</div><div> *</div><div> * @since JavaFX 24.0</div><div> *</div><div> * @author David Kopp</div><div> */</div><div>public final class ApplicationMenu {</div><div><br></div><div>    /**</div><div>     * Package scope constructor to create the ApplicationMenu object.</div><div>     */</div><div>    ApplicationMenu() {</div><div>    }</div><div><br></div><div>    /**</div><div>     * Installs a handler to show a custom about window for your application.</div><div>     * <p></div><div>     * Setting the handler to null reverts it to the default behavior.</div><div>     *</div><div>     * @param handler the handler</div><div>     */</div><div>    public void setAboutHandler(Runnable handler) {</div><div>        PlatformImpl.setAboutHandler(handler);</div><div>    }</div><div><br></div><div>    /**</div><div>     * Installs a handler to show a custom settings window for your application.</div><div>     * <p></div><div>     * Setting the handler to null reverts it to the default behavior.</div><div>     *</div><div>     * @param handler the handler</div><div>     */</div><div>    public void setSettingsHandler(Runnable handler) {</div><div>        PlatformImpl.setSettingsHandler(handler);</div><div>    }</div><div>}</div></div><div><br></div><div>Added to GtkApplication:</div><div><br></div><div><div>    @Override</div><div>    public void setAboutHandler(Runnable handler) {</div><div>        aboutHandler = handler;</div><div>        rebuildGtkMenu();</div><div>    }</div><div><br></div><div>    @Override</div><div>    public void setSettingsHandler(Runnable handler) {</div><div>        settingsHandler = handler;</div><div>        rebuildGtkMenu();</div><div>    }</div><div><br></div><div>    private void rebuildGtkMenu() {</div><div>        for (int index = this.gtkMenu.getItems().size() - 1; index >= 0; index--) {</div><div>            this.gtkMenu.remove(index);</div><div>        }</div><div><br></div><div>        if (null != aboutHandler) {</div><div>            MenuItem aboutMenu = createMenuItem("About " + getName(), new MenuItem.Callback() {</div><div>                @Override public void action() {</div><div>                    aboutHandler.run();</div><div>                }</div><div>                @Override public void validate() {</div><div>                }</div><div>            });</div><div>            this.gtkMenu.add(aboutMenu);</div><div>            this.gtkMenu.add(MenuItem.Separator);</div><div>        }</div><div><br></div><div>        if (null != settingsHandler) {</div><div>            MenuItem preferencesMenu = createMenuItem("Settings...", new MenuItem.Callback() {</div><div>                @Override public void action() {</div><div>                  settingsHandler.run();</div><div>                }</div><div>                @Override public void validate() {</div><div>                }</div><div>            }, ',', KeyEvent.MODIFIER_COMMAND);</div><div>            this.gtkMenu.add(preferencesMenu);</div><div>            this.gtkMenu.add(MenuItem.Separator);</div><div>        }</div><div>    }</div><div><br></div><div>    public void installGtkMenu(MenuBar menubar) {</div><div>        this.gtkMenu = createMenu("GTK");</div><div><br></div><div>        rebuildGtkMenu();</div><div><br></div><div>        menubar.add(this.gtkMenu);</div><div>    }</div><div><br></div><div>    @Override public void installDefaultMenus(MenuBar menubar) {</div><div>        checkEventThread();</div><div>        installGtkMenu(menubar);</div><div>    }</div><div><br></div></div><div>MacApplication stays the same.</div></div></body></html>