本文介绍了在macOS上本地化Java Swing应用程序中的Spotlight for Help的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在macOS上的Java Swing应用程序中,Cocoa自动绑定名为到框架菜单栏中标记为帮助"的第一个菜单和感觉和屏幕菜单栏.

In Java Swing applications on macOS, Cocoa automatically binds a search field called Spotlight for Help to the first menu labelled "Help" in a frame’s menu bar, when using the macOS look and feel and a screen menu bar.

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"在其他语言环境中转换为

However my application is localized and the English string "Help" translates in other locales into

  • "助手"法文;
  • " Aiuto "(意大利语);
  • " Ayuda "(西班牙语);
  • 葡萄牙语中的
  • " Ajuda ";
  • " Hilfe "(德语);
  • " Hulp "(荷兰语);
  • 瑞典文中的
  • "Hjälp".
  • "Aide" in French;
  • "Aiuto" in Italian;
  • "Ayuda" in Spanish;
  • "Ajuda" in Portuguese;
  • "Hilfe" in German;
  • "Hulp" in Dutch;
  • "Hjälp" in Swedish.

在这种情况下,Cocoa不会在帮助菜单中""提供Spotlight for help字段.

In these cases, the Spotlight for Help field is not supplied to the help menu by Cocoa.

我如何仍能获得此搜索字段?

推荐答案

解决方案

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

将出现搜索字段Spotlight for Help.

The search field Spotlight for Help will appear.

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

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.

尽管大多数消息人士都说过,但Swing根植于系统调用,因此依赖于OS来实现许多功能,例如本例.理想情况下,应使用 setHelpMenu(JMenu) ,但是您会发现这从未实现.

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.

如果先检查一下,您会发现 JMenuBar ,您对此无能为力.如果您尝试使用AWT的 MenuBar 取而代之的是,您会看到行为是完全一样的,尽管足够有趣的是,方法 setHelpMenu(Menu) 它确实已实现,但如果菜单的名称与"Help"不同,则不会添加搜索字段.

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".

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

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".

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

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

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

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

  • 要求将应用程序捆绑在.app目录中并包含Contents/Resources/<os-locale>.lproj目录,以便OS识别该应用程序支持的OS语言环境,因此需要一个标有的菜单操作系统本地化的 "Help"字符串,以便将操作系统本地化的搜索字段添加到该菜单中;
  • 否则,操作系统会将应用程序视为本地化的en_US,因此需要一个标有en_US本地化的"Help"字符串的菜单,以便将en_US本地化的搜索字段添加到该菜单. /li>
  • 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.

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

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.

请注意,Apple有自己的机制来强制应用程序使用不同于操作系统语言环境的其他语言环境,并且它使用的是-AppleLanguages选项(open <application>.app --args -AppleLanguages "(<locale>)"). 语言切换器实用程序在后台具有相同的功能.同样,应该存在相应的Contents/Resources/<locale>.lproj目录,否则操作系统会将应用程序视为en_US本地化.

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.

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

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.

屏幕截图

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

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.

这篇关于在macOS上本地化Java Swing应用程序中的Spotlight for Help的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 19:41