我正在努力在 MacOS 上运行的 JavaFX 应用程序中正确实现应用程序菜单栏。
从 JDK9 开始,似乎支持在 Mac 上正确设置应用程序菜单的方法是:
javapackager
1)用工具打包应用程序。
2) 通过包中的 API 为 About/Preferences/FileOpen/Print/ 等事件提供事件处理java.awt.desktop
程序。
(我发现必须首先从主线程获取单例桌面实例,而不是从 JavaFX 线程获取单例桌面实例,否则提供的事件处理程序将被忽略。)
3) 设置将useSystemMenuBar
主舞台的菜单栏向上移动到 Apple 系统菜单中。
我的问题是 2) 和 3) 似乎彼此不兼容。也就是说,我可以将菜单栏移动到系统菜单栏中,或者我可以处理 About/Prefs 事件,但不能同时处理:
import javafx.fxml.FXML
import javafx.fxml.FXMLLoader
import javafx.scene.Scene
import javafx.scene.control.MenuBar
import javafx.scene.layout.Pane
import javafx.stage.Stage
class Controller()
{
@FXML var menubar: MenuBar = _
def initialize(): Unit = menubar.setUseSystemMenuBar(true) // EITHER THIS
}
class Menu extends javafx.application.Application
{
def start(stage: Stage): Unit =
{
val l = new FXMLLoader(getClass.getResource(s"/menu.fxml"))
stage.setScene(new Scene(l.load[Pane]))
stage.setTitle("Menu")
stage.show()
}
}
object Main
{
def main(args: Array[String]) =
{
val d= java.awt.Desktop.getDesktop // OR THIS
javafx.application.Application.launch(classOf[Menu], args: _*)
}
}
这里发生了什么?
在线可用的文档(来自 Apple、Oracle 等)是不稳定的、零散的,并且通常没有多大帮助。
(我知道 Jay Gassen 的 NSMenuFX 库,虽然它很棒,但我认为这不是一个可行的长期解决方案:它使用反射进入底层 Glass 系统,以丢弃 Apple 运行时提供的默认菜单栏和直接使用系统菜单进行猴子 - 我希望此方法在即将发布的 JDK(版本 10?)中失败,因为 JVM 运行时模块系统将不再允许对不可访问的类进行反射。)