如何将 Spotlight for Help 插入本地化的 macOS 应用程序? [英] How to insert Spotlight for Help into localized macOS applications?

查看:27
本文介绍了如何将 Spotlight for Help 插入本地化的 macOS 应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 macOS 上使用 Swing GUI 框架实现 Java 应用程序.当使用系统外观和屏幕菜单栏时,Swing会自动插入一个搜索字段,名为

System.setProperty("apple.laf.useScreenMenuBar", "true");尝试 {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());} 捕获(异常 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,因为字符串不同:

解决方案

解决方案

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

将出现 Spotlight for Help 搜索字段.

说明

我要猜测一下,您是直接执行 .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/.lproj 目录,以便操作系统识别应用程序支持的操作系统区域设置,因此需要一个标有 OS-localized Help" 字符串的菜单,以便添加操作系统本地化搜索该菜单的字段;
  • 否则,操作系统将应用程序视为 en_US 本地化,因此需要一个带有 en_US 本地化 Help" 标签的菜单字符串,以便将 en_US 本地化搜索字段添加到该菜单.

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

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

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

截图

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

I am implementing a Java application using the Swing GUI framework on macOS. When using the system look and feel and a screen menu bar, Swing automatically inserts a search field called Spotlight for Help into the first menu labelled "Help" of the menu bar of a frame:

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

As my application is localized, the English string "Help" is different in other locales (e.g. "Aide" in French). But in those cases Swing does not insert Spotlight for Help since the string is different:

解决方案

Solution

  1. Bundle the .class files and resources (image, sound, video, localization files, etc.) of your application in a .jar file with Oracle's Java Archive.
  2. Bundle your .jar file in an .app directory with Oracle's AppBundler (for Java 7+, which replaces the old Apple's JarBundler for Java 6).
  3. Add to the .app directory the Contents/Resources/<locale>.lproj directories for each locale that should be supported by your application (you can let the locale directories empty since the localization files can be already in the .jar file).
  4. Launch your application (double-click on the application icon in Finder or type open <application>.app in Terminal).

The search field Spotlight for Help will appear.

Explanation

I'm going to make a guess and it's that you're executing the .class files directly (from an IDE, for instance) or the .jar file, because from what I know this should be working.

Although what most sources say, Swing is deeply rooted on system calls and thus relies on the OS for many features, like in this case. Ideally, this should be covered by the method setHelpMenu(JMenu) but as you'll notice this has never been implemented.

If you check first, you'll notice that there's no extra component added in your JMenuBar and you have no control over that. If you try using AWT's MenuBar instead you'll see the behavior is exactly the same although, insterestingly enough, the method setHelpMenu(Menu) it is really implemented but doesn't add the search field if the menu is named something different from "Help".

At this point I found a workaround and it's setting the menu label to "Help" and once displayed (don't use ComponentListener.componentShown(ComponentEvent), this won't work, use AncestorListener.ancestorAdded(AncestorEvent)) changing the menu label to the localized one. This will add the search field to the help menu. However the search field will in English, with the label "Search".

Checking the API, it's more than clear that in Swing this feature is not implemented and fully relies on AWT. AWT on the other hand has partly implemented the native calls to the OS, but it's not wired to be invokable. Reaching this point and knowing that the search field does appear in our application and that in other ones running in Java it's properly localized lets us hint that this is a trait of the OS itself (I might be wrong at this point and it's really AWT doing the dirty job, but wasn't able to find any piece of code that does it directly, although in Objective C you can define any).

Reading the documentation about how to localize a Java application in MacOS, we note that:

  • it's a requirement that the application be bundled in an .app directory and contain the Contents/Resources/<os-locale>.lproj directory, so that the OS recognizes the OS locale as supported by the application, and consequently expects a menu labeled with the OS-localized "Help" string in order to add the OS-localized search field to that menu;
  • otherwise, the OS treats the application as en_US localized, and consequently expects a menu labeled with the en_US-localized "Help" string in order to add the en_US-localized search field to that menu.

Now you can type open <application>.app in Terminal and your application will be launched with the OS-localized search field added to the help menu.

Note that Apple has its own mechanism for forcing the application to use another locale than the OS locale, and it's using the -AppleLanguages option (open <application>.app --args -AppleLanguages "(<locale>)"). The Language Switcher utility does the same under the hood. Again, the appropriate Contents/Resources/<locale>.lproj directory should exist, otherwise the OS will treat the application as en_US localized.

How you make an .app directory from the .class files and resources (image, sound, video, localization files, etc.) of your application is beyond the scope of this question because it varies depending on the platform you're using, but Oracle provides the Java Archive (to make the intermediary .jar file) and AppBundler (to make the .app directory) utilities.

Screenshot

The OS is localized in Spanish in this screenshot but the application is localized in French, because it's been launched with the -AppleLanguages "(fr)" option.

这篇关于如何将 Spotlight for Help 插入本地化的 macOS 应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆