Spotlight for help for macOS上的本地化Java Swing应用程序

Mag*_*ero 6 java macos swing localization spotlight

在macOS上的Java Swing应用程序中,当使用macOS 外观和屏幕菜单栏时,Cocoa会自动将名为Spotlight for Help的搜索字段绑定到框架菜单栏中标有"Help"的第一个菜单.

带搜索功能的帮助菜单

System.setProperty("apple.laf.useScreenMenuBar", "true");

try {
  UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
  e.printStackTrace();
}

JFrame frame = new JFrame();
JMenuBar menuBar = new JMenuBar();
JMenu helpMenu = new JMenu("Help");
menuBar.add(helpMenu);
frame.setJMenuBar(menuBar);
Run Code Online (Sandbox Code Playgroud)

但是我的应用程序已本地化,英语字符串"帮助"在其他语言环境中转换为

  • 法语中的" 助手 ";
  • 意大利语中的" Aiuto ";
  • 西班牙语中的" Ayuda ";
  • 葡萄牙语中的" Ajuda ";
  • 德语中的" Hilfe ";
  • " Hulp "荷兰语;
  • 瑞典语中的" Hjälp ".

在这些情况下,Cocoa 不会向帮助菜单提供Spotlight for Help字段.

没有搜索功能的帮助菜单

我怎么还能得到这个搜索字段?

Yag*_*dal 3

解决方案

  1. 使用 Oracle 的Java Archive将应用程序的文件.class和资源(图像、声音、视频、本地化文件等)捆绑在一个文件中。.jar
  2. 使用 Oracle 的AppBundler(适用于 Java 7+,它取代了旧的 Apple 的JarBundler)将文件捆绑.jar在目录中.app目录中。
  3. 将应用程序应支持的每个语言环境的目录添加到.app目录Contents/Resources/<locale>.lproj中(您可以将语言环境目录留空,因为本地化文件可能已经在.jar)。
  4. 启动您的应用程序(双击 Finder 中的应用程序图标或open <application>.app在终端中键入)。

将出现“帮助”搜索字段 Spotlight。

解释

我将进行猜测,您是.class直接执行文件(例如,从 IDE)还是.jar执行文件,因为据我所知,这应该可以正常工作。

尽管大多数消息来源都说,Swing 深深植根于系统调用,因此依赖操作系统来实现许多功能,就像在本例中一样。理想情况下,该方法应该涵盖这一点setHelpMenu(JMenu),但您会注意到这从未实现过

如果您先检查,您会发现您的文件中没有添加额外的组件,JMenuBar并且您无法控制它。如果您尝试使用 AWT,MenuBar您会发现行为完全相同,但有趣的是,setHelpMenu(Menu)它确实实现了方法,但如果菜单的名称与"Help".

此时,我找到了一种解决方法,它将菜单标签设置为"Help",一旦显示(不要使用ComponentListener.componentShown(ComponentEvent),这不起作用,使用AncestorListener.ancestorAdded(AncestorEvent))将菜单标签更改为本地化的标签。这会将搜索字段添加到帮助菜单中。但是,搜索字段将为英文,并带有标签"Search"

检查 API,很明显在 Swing 中该功能并未实现,而是完全依赖于 AWT。另一方面,AWT部分实现了对操作系统的本机调用,但它并不可调用。到达这一点并知道搜索字段确实出现在我们的应用程序中,并且在 Java 中运行的其他应用程序中它已正确本地化,这让我们暗示这是操作系统本身的一个特征(在这一点上我可能是错的,它实际上是 AWT 在做肮脏的工作,但无法找到任何直接执行此操作的代码,尽管在 Objective C 中您可以定义任何代码)。

阅读有关如何在 MacOS 中本地化 Java 应用程序的文档,我们注意到:

  • 要求应用程序捆绑在一个.app目录中并包含该Contents/Resources/<os-locale>.lproj目录,以便操作系统识别应用程序支持的操作系统区域设置,因此需要一个标有操作系统本地化 "Help"字符串的菜单,以便添加操作系统本地化的字符串该菜单的搜索字段;
  • 否则,操作系统将应用程序视为en_US本地化的,因此需要一个标有en_US-localized"Help"字符串的菜单,以便将en_US-localized 搜索字段添加到该菜单。

现在,您可以在终端中输入open <application>.app,您的应用程序将启动,并且操作系统本地化的搜索字段将添加到帮助菜单中。

请注意,Apple 有自己的机制来强制应用程序使用操作系统区域设置之外的其他区域设置,并且它使用选项-AppleLanguages( open <application>.app --args -AppleLanguages "(<locale>)")。语言切换实用程序在底层执行相同的操作。同样,适当的Contents/Resources/<locale>.lproj目录应该存在,否则操作系统会将应用程序视为en_US本地化的。

如何从应用程序的文件和资源(图像、声音、视频、本地化文件等)创建.app目录.class超出了本问题的范围,因为它根据您使用的平台而有所不同,但 Oracle 提供了Java Archive(用于创建中间.jar文件)和AppBundler(用于创建.app目录)实用程序。

截屏

本地化搜索字段

在此屏幕截图中,操作系统已本地化为西班牙语,但应用程序已本地化为法语,因为它是通过该-AppleLanguages "(fr)"选项启动的。