【问题标题】:How to insert Spotlight for Help into localized macOS applications?如何将 Spotlight for Help 插入本地化的 macOS 应用程序?
【发布时间】:2017-07-26 00:41:22
【问题描述】:

我正在 macOS 上使用 Swing GUI 框架实现一个 Java 应用程序。当使用 system 外观和 screen 菜单栏时,Swing 会自动将名为 Spotlight for Help搜索字段 插入到标有 @ 的第一个菜单中一帧菜单栏的987654326@:

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);

由于我的应用程序已本地化,英文字符串 "Help" 在其他语言环境中有所不同(例如,"Aide" 在法语中)。但在这些情况下,Swing 不会插入 Spotlight for Help,因为字符串不同:

【问题讨论】:

    标签: java macos swing localization spotlight


    【解决方案1】:

    解决方案

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

    将出现搜索字段 Spotlight for Help。

    说明

    我要猜测一下,您正在直接执行 .class 文件(例如,从 IDE 执行)或 .jar 文件,因为据我所知,这应该是工作。

    尽管如大多数消息来源所说,Swing 深深植根于系统调用,因此在许多功能上都依赖于操作系统,就像在本例中一样。理想情况下,这应该被 setHelpMenu(JMenu) 方法覆盖,但您会注意到 this has never been implemented

    如果您先检查,您会注意到您的JMenuBar 中没有添加额外的组件,并且您无法控制它。如果您尝试使用 AWT 的 MenuBar,您会看到行为完全相同,但有趣的是,setHelpMenu(Menu) 方法确实已实现,但如果菜单名称与 @ 不同,则不会添加搜索字段987654356@.

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

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

    阅读有关how to localize a Java application in MacOS 的文档,我们注意到:

    • 要求应用程序捆绑在.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>)")。 Language Switcher 实用程序在后台执行相同的操作。同样,应该存在适当的Contents/Resources/<locale>.lproj 目录,否则操作系统会将应用程序视为en_US 本地化。

    您如何从应用程序的.class 文件和资源(图像、声音、视频、本地化文件等)中获取make an .app directory 超出了此问题的范围,因为它因您使用的平台而异,但 Oracle 提供了 Java Archive(制作中间 .jar 文件)和 AppBundler(制作 .app 目录)实用程序。

    截图

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

    【讨论】:

    • 这解决了我的问题,谢谢。我编辑了您的答案,建议使用 Apple 的 JarBundler(适用于 Java 6),因为它是一个已被 Oracle 的 AppBundler(适用于 Java 7+)取代的遗留程序。
    • 太好了,很高兴了解 AppBundler。您还删除了解释为什么直接运行类不显示除en_US 以外的语言环境的部分,我发现了解最初发生的事情很重要。无论如何,我把它留给你,因为如果你觉得得到回答,我是谁来反驳你。
    • 我发现您的句子“Java 被定义为仅适用于语言en_US”模棱两可,因此不理解您的最后一段,这就是我首先删除它的原因。但现在我知道你的意思了:当没有包含 <application>.app 的捆绑包时,macOS 假定语言环境是 en_US(因此需要一个标有英文字符串 "Help" 的菜单,它可以在其中添加 Spotlight 字段)名为Contents/Resources/<locale>.lproj 的目录。我已经相应地改进了答案。再次感谢您提供完整的答案。
    • 我刚刚找到了另一种方法(请参阅下面的答案)。
    【解决方案2】:

    我刚刚发现了另一种方法。无需在.app目录中添加空的Contents/Resources/<locale>.lproj目录,只需在.app目录的Contents/Info.plist文件中添加这两行(键值对)即可:

    <key>CFBundleAllowMixedLocalizations</key>
    <true />
    

    制作.app 包的新方法是使用Oracle 的JavaPackager 命令行实用程序,它是J.D.K. 的一部分。它会生成一个.app 目录,其中Contents/Info.plist 默认具有上述两行(无需在命令行中将键值对作为javapackager 的选项传递)。并且使用open &lt;application&gt;.app --args -AppleLanguages "(&lt;locale&gt;)" 命令强制使用另一个语言环境确实适用于 Oracle 的 JavaPackager 生成的 &lt;application&gt;.app 目录,这与 Oracle 的 AppBundler 生成的目录相反。

    【讨论】:

    • 我记得在某个时候尝试过这个,但对我没有用,但确实有效。关于 JavaPackager,如果您查看我的原始回复,我故意省略了可用的不同工具,解释了问题并提出了一些建议来看看(例如,我使用 Maven 插件),因为每个工具都有自己的特殊性。这就是为什么我不喜欢繁重的编辑,但只要社区批准,我就没事。
    猜你喜欢
    • 2012-04-22
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多