Spotlight for help in localized Java Swing applications on macOS

In Java Swing applications on macOS Cocoa, the Spotlight search field for help in the first menu is automatically linked to the Help text in the frames menu bar when using the macOS look and menu bar on the screen.

Help menu with search function

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

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

  • "Assistant" in French;
  • "Aiuto" in Italian;
  • "Ayuda" in Spanish;
  • "Ajuda" in Portuguese;
  • "Hilfe" in German;
  • "Help" in Dutch;
  • "HjΓ€lp" in Swedish.

In these cases, the Spotlight field for reference is not provided in the Cocoa Help menu.

Help menu without search function

How can I get this search box?

+6
source share
2 answers

Decision

  • Bundle .class files and resources (images, sound, video, localization files, etc.) of your application in .jar with Oracle Java Archive .
  • Bundle your .jar file in the .app directory with the Oracle AppBundler (for Java 7+, which replaces the old Apple JarBundler for Java 6).
  • Add the Contents/Resources/<locale>.lproj directories to the .app directory for each locale that your application should support (you can let the locale directories be empty, since the localization files may already be in the .jar file).
  • Launch the application (double-click the application icon in Finder or enter open <application>.app in Terminal).

The Spotlight search box appears for reference.

Explanation

I am going to make an assumption, and that you are executing .class files directly (for example, from the IDE) or a .jar file, because from what I know this should work.

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

If you check first, you will notice that no additional component has been added to your JMenuBar , and you have no control over this. If you try to use the AWT MenuBar , you will see that the behavior is exactly the same, although, oddly enough, the setHelpMenu(Menu) it is really implemented, but does not add a search field if the menu says something other than "Help" .

At this point, I found a workaround and set the menu label "Help" and displayed once (do not use ComponentListener.componentShown(ComponentEvent) , this will not work, use AncestorListener.ancestorAdded(AncestorEvent) ), changing the menu shortcut to localized. This will add a search field to the help menu. However, the search box will be in English labeled "Search" . "Search"

Checking the API, it is more than clear that this function is not implemented in Swing and relies entirely on AWT. AWT, on the other hand, partially implemented its own OS calls, but it is not connected to be invokable . Having reached this point and knowing that the search field appears in our application, and that it is correctly localized in others working in Java, it allows us to hint that this is a feature of the OS itself (I may be wrong at this stage, and it really makes AWT dirty work, but could not find any piece of code that does this directly, although you can define any in Objective-C).

Reading the documentation on how to localize a Java application on MacOS , note that:

  • this requirement is that the application be .app in the .app directory and contain the Contents/Resources/<os-locale>.lproj , so that the OS recognizes the OS locale supported by the application, and therefore expects a menu marked with the localized "Help" OS, To add a localized OS search field to this menu;
  • otherwise, the OS considers the application as en_US localized and, therefore, expects a menu labeled en_US -localized "Help" to add an en_US localized search field to this menu.

Now you can enter open <application>.app in Terminal, and your application will start with a localized search on the OS added to the help menu.

Please note that Apple has its own mechanism for forcing the application to apply to a different language than the OS locale, and using the -AppleLanguages option ( open <application>.app --args -AppleLanguages "(<locale>)" ). The Language Switcher utility does the same under the hood. Again, the corresponding directory Contents/Resources/<locale>.lproj must exist, otherwise the OS will consider the application as en_US localized.

How you create a .app directory from .class files and resources (images, sound, video, localization files, etc.) of your application is beyond the scope of this question, since it depends on the platform you use, but Oracle provides a Java Archive (to make an intermediate .jar file) and AppBundler (to make the .app utility).

Screenshot

Localized search field

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

+3
source

I just found out a different way. There is no need to add empty Contents/Resources/<locale>.lproj directories to the .app directory, just adding these two lines (key-value pair) to the Contents/Info.plist the .app directory:

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

And a new way to create an .app package is to use the Oracle JavaPackager command line utility, which is part of the JDK. It generates a .app directory with Contents/Info.plist , which by default has two lines (there is no need to pass a key-value pair as a javapackager option in command line). And forcing another language with the open <application>.app --args -AppleLanguages "(<locale>)" <application>.app does work with the <application>.app created by Oracle JavaPackager, contrary to the one created by Oracle AppBundler.

+1
source

Source: https://habr.com/ru/post/1015515/


All Articles