0x4a616e / nsmenufx Goto Github PK
View Code? Open in Web Editor NEWThis project forked from codecentric/nsmenufx
Full macOS menu bar access for JavaFX apps
License: Other
This project forked from codecentric/nsmenufx
Full macOS menu bar access for JavaFX apps
License: Other
Just started trying to implement this library into an app of mine, and I got it properly showing the menu at the top of the screen in MacOs, but when I create new scenes (with new stages) they get a copy of the menu placed on them as you can see in the attached screen shot.
How do I prevent this from happening?
What is the recommended approach to update the MenuBar contents at runtime, sometime after Application start? For instance, adding or removing Menus or disabling particular MenuItems depending on the application state.
Keeping a reference to the MenuBar passed to setGlobalMenuBar
and adding/removing items etc. later seems to have no effect, nor does building and setting an entirely new MenuBar.
Happy to send a PR with a new sample and doc entry for this once it's clear.
Thanks for the library!
I've changed my application to use the new (3.0.1) version of NSMenuFx. Now when I create a PopupWindow I get this UnsatisfiedLinkError (stack trace below). The only difference is switching to the new NSMenuFx. If I revert to the older version (2.x) it goes away.
I haven't done any testing other than rearrange my code a little and then I get an error with a different popup that is created first. I'll try to create a small test app, but I thought I'd post this first in case anyone has an idea what is happening.
I'm using JDK 11.0.9.1 and JavaFX 15
Caused by: java.lang.UnsatisfiedLinkError: 'void com.sun.glass.ui.mac.MacTimer._resume(long)'
at com.sun.glass.ui.mac.MacTimer._resume(Native Method)
at com.sun.glass.ui.Timer.resume(Timer.java:153)
at com.sun.javafx.tk.quantum.QuantumToolkit.resumeTimer(QuantumToolkit.java:513)
at com.sun.javafx.tk.quantum.QuantumToolkit$PulseTask.set(QuantumToolkit.java:204)
at com.sun.javafx.tk.quantum.QuantumToolkit.requestNextPulse(QuantumToolkit.java:890)
at javafx.scene.Parent.markDirtyLayout(Parent.java:939)
at javafx.scene.Parent.requestLayout(Parent.java:963)
at javafx.scene.Scene$8.invalidated(Scene.java:1228)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147)
at javafx.scene.Scene.setRoot(Scene.java:1178)
at javafx.scene.Scene.(Scene.java:356)
at javafx.scene.Scene.(Scene.java:207)
at javafx.scene.Scene$2$1.(Scene.java:434)
at javafx.scene.Scene$2.createPopupScene(Scene.java:434)
at com.sun.javafx.scene.SceneHelper.createPopupScene(SceneHelper.java:99)
at javafx.stage.PopupWindow.(PopupWindow.java:158)
at javafx.scene.control.PopupControl.(PopupControl.java:115)
at javafx.scene.control.ContextMenu.(ContextMenu.java:144)
Hello,
I was playing around with this project to make use of it in JavaFX Scene Builder. Unfortunately it dependes on JavaFX 11 wich somehow then breaks the Scene Builde build. After playing around I found that its compatible with JavaFX 19.
Would upgrading to JavaFX19/Java17 be okay?
Thanks!
I have the same issue like described here:
https://stackoverflow.com/questions/22569046/how-to-make-an-os-x-menubar-in-javafx/39627830#39627830
I cannot open the menu bar until I switch to another app and back to my JavaFX app. Then everything works as expected.
Do you have an idea what the problem is here?
I use OpenJDK 15 and JavaFX 15. I add a default app menu like this:
var tk = MenuToolkit.toolkit();
var defaultApplicationMenu = tk.createDefaultApplicationMenu("BCM");
tk.setApplicationMenu(defaultApplicationMenu);
Then on a stage I'm adding a menu bar like this:
var fileMenu = MenuBarUtil.createMenu(MenuType.file);
MenuBarUtil.addMenuItemToMenu(fileMenu, MenuItemType.fileClose, this::close);
var menuBar = new MenuBar();
menuBar.setUseSystemMenuBar(true);
menuBar.getMenus().add(fileMenu);
gridPane.add(menuBar, 0, 0);
The helper class just adds some menu items with some key code combinations as accelerators.
I create a Preferences... menu item as follows:
final MenuItem preferencesMenuItem = new MenuItem("Preferences...");
preferencesMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.COMMA, KeyCodeCombination.META_DOWN));
preferencesMenuItem.setOnAction(this::handleOptionsMenuItemAction);
When the menu is displayed, however, the accelerator shows as โC (see screen shot)
It works as expected, using the older version (2.18) i.e should be โ, (which is the expected key combination on Mac)
Would be great if you could add this badge to your readme.
[![JFXCentral](https://img.shields.io/badge/Find_me_on-JFXCentral-blue?logo=googlechrome&logoColor=white)](https://www.jfx-central.com/libraries/nsmenufx)
FYI, this line:
MenuToolkit.toolkit().setAppearanceMode(AppearanceMode.DARK);
...works with Swing as well. Combining that one line with the following:
https://www.formdev.com/flatlaf/
...and (amazingly) the following line...
System.setProperty("apple.laf.useScreenMenuBar", "true");
...is now giving me an astonishingly modern looking Swing app on macOS, with IntelliJ-style theme options, macOS menu bar, and window decorations that match the OS.
I'd suggest updating the documentation to reflect that the library is hugely useful for Swing as well as JavaFX.
Also, P.S. thanks for this - very helpful!
Does NSMenuFX currently not work with jlink?
I tried importing the library in my pom.xml:
<dependency>
<groupId>de.jangassen</groupId>
<artifactId>nsmenufx</artifactId>
<version>3.0.1</version>
</dependency>
then added the nsmenufx module to module-info.java:
open module com.utsusynth.utsu {
requires javafx.controls;
requires javafx.fxml;
requires javafx.media;
requires java.desktop;
requires org.apache.commons.io;
requires jdk.charsets;
requires jdk.localedata;
requires com.google.guice;
requires nsmenufx;
exports com.utsusynth.utsu;
}
The library works fine when I run it locally (mvn javafx:run) but when I try to deploy with jlink (mvn javafx:jlink) I get the does-not-work-with-jlink error:
Error: automatic module cannot be used with jlink: com.sun.jna
I had assumed from codecentric#36 that this fork would be jlink-compatible, but is it not there quite yet? Or is there another dependency/module I'm not adding properly? Thanks!
Follow up of codecentric#16
When creating a menubar, it is not accessible (i.e. cannot be clicked) unless you do an ALT-TAB application switch twice. Then everything runs fine.
I tested it under Mac OS Big Sur and Mac OS Ventura.
This is the code that generates the menus
MenuToolkit tk = MenuToolkit.toolkit();
MenuBar bar = new MenuBar();
Menu applicationMenu = tk.createDefaultApplicationMenu(APP_NAME, aboutStageBuilder.build());
bar.getMenus().addAll(applicationMenu,
this.menu_properties);
//remove the "traditional" menu bars
parent.getChildren().remove(this.menubar);
parent.getChildren().remove(this.menubar_version);
// set the new menu bar.
tk.setAppearanceMode(AppearanceMode.AUTO);
tk.setGlobalMenuBar(bar);
Hello!
I included NSMenuFX in my application.
After the start of the application the MenuBar is not responsive (does not respond to any clicks).
Only after changing back-and-forth to another app and then to my app again the MenuBar will eventually respond.
I was able to reproduce the behavior with the SampleApp (de.jangassen.nsmenufx.samples.SampleMenuBar).
Environment is macOS Big Sur (v11.2.3), AdoptOpenJDK 11.0.10+9. See screenshot for JavaFX libs.
Any ideas?
Thanks and best regards
Stephan
I migrated from the old version(2.1.8) to 3.0.0-BETA2, which was very straight forward.
When I try running my application, however, I noticed that the MenuItem events aren't always working. For example, when I click on the About menu item, or the Preferences menu item (that I created), the events don't work consistently. They work sometimes, but not all the time (seem to work about 10% of the time). Same thing when I try the Quit menu item; sometimes the application exits, but mostly not.
The code I am using, is the same as for the old version, and when I revert to the the older version, the events work was expected.
I also tried using the defaultApplicationMenu (using createDefaultApplicationMenu()
), but the same problem occurs.
I'm not sure why sometimes it works and sometimes not; maybe a timing issue.
Also note: I am using JavaFX 15.0.1. (I'm not sure if that matters.)
Using the KeyCode.SHORTCUT
constant doesn't work for adding keyboard shortcuts with the Command key.
The same issue was reported in codecentric#42 .
The shortcut key is a virtual key that is used to represent different keys on different platforms (in order to create platform-independent keyboard shortcuts). Here's a part of the Javadoc for KeyCombination
:
/**
* ...
* The {@code shortcut} modifier is used to represent the modifier key which is
* used commonly in keyboard shortcuts on the host platform. This is for
* example {@code control} on Windows and {@code meta} (command key) on Mac.
* By using {@code shortcut} key modifier developers can create platform
* independent shortcuts. So the "Shortcut+C" key combination is handled
* internally as "Ctrl+C" on Windows and "Meta+C" on Mac.
* ...
*/
This is a suggestion for an enhancement.
The api already provides several convenience methods to create some standard menu items such as the Quit menu, Hide menu, Minimize menu, etc.
It would be useful to a have a method that creates the Preferences menu, which most application would have. The method could return a MenuItem with the name (Preferences...) and accelerator keys (โ,). The user could then add an Event handler. Better yet, the method could take in the Event handler, as a parameter, so calling it might look something like this:
MenuItem prefsMenuItem = toolkit.createPreferencesMenuItem(event -> handlePreferences(event))
If you set the MenuToolkit.setForceQuitOnCmdQ(false), you can now no longer quit the application when using CMD Q or the application menu Quit command.
This worked correctly in the CodeCentric NSMenuFX branch.
Do you know of any reason why this doesn't work? It is preventing us from using your fork.
Thanks
Hi,
I am working from time to time on JavaFX Scene Builder.
There are few issues related MacOS behavior open.
Are you looking for support on this project? How about preparing this so, that it could possibly be ported into OpenJFX main code?
Thanks!
When running my application on macOS, I noticed the Application menubar was not showing any more, and I saw the following in the console:
Warning: MenuBar ignored property useSystemMenuBar because menus contain CustomMenuItem
I recently added a submenu that uses CustomMenuItem. When I removed that, the menubar worked again.
I did some digging, and it looks like the warning message comes from the MenuBarSkin class:
private boolean menusContainCustomMenuItem() {
for (Menu menu : getSkinnable().getMenus()) {
if (menuContainsCustomMenuItem(menu)) {
System.err.println("Warning: MenuBar ignored property useSystemMenuBar because menus contain CustomMenuItem");
return true;
}
}
return false;
}
On Windows (where I am not using NSMenuFX), using CustomMenuItem works fine. Is there some reason why CustomMenuItem doesn't work with NSMenuFX?
Thanks for your help.
I've had a problem recently where the video memory of canvases in my JavaFX stages is not released when I remove the stage and I run out of memory.
The problem goes away if I remove (along with a few other things in my code) the use of autoAddWindowMenuItems for the Window menu.
I think the problem is from the following methods in WindowMenuUpdateListener.
addWindowMenuItem adds a reference to the stage in createdMenuItems, but removeWindowMenuItem doesn't remove it.
So even though you remove the stage it isn't properly garbage collected as there is still a reference to it.
private void removeWindowMenuItem(Stage stage, Menu menu) {
MenuItem menuItem = createdMenuItems.get(stage);
if (menuItem != null) {
menu.getItems().remove(menuItem);
}
}
private void addWindowMenuItem(Stage stage, Menu menu) {
CheckMenuItem item = new CheckMenuItem(stage.getTitle());
item.setOnAction(event -> stage.toFront());
createdMenuItems.put(stage, item);
menu.getItems().add(item);
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.