Chapter 28. Internationalization and Accessibility

Like any commercial-quality product, Eclipse is fully internationalizable and pays attention to accessibility requirements. When contributing to Eclipse we want to preserve this characteristic and make sure that our plug-in is usable by anybody. In this section we look into tasks related to internationalization and accessibility:

  • Externalizing the strings from the plugin.xml

  • Externalizing strings from Java code

  • Paying attention to accessibility

All these tasks are highly mechanical, but need to be done. Let's start with externalizing the strings from the plugin.xml.

Externalizing Strings from the Manifest Files

Some strings in the plugin.xml are shown to the end user, the label of an action, for example. Others are shown to the plug-in developer through PDE, like the name of an extension point. All these strings need to be translatable and need to be externalized. PDE supports this with the look-aside file plugin.properties, shown in Figure 28.1.

Externalizing Strings from the Manifest Files

A string prefixed with “%” in the plugin.xml is looked up in the plugin.properties file. We have to externalize all of the extension point names and all of the user-visible strings in our contributions. Here is an excerpt from the externalized plugin.xml file:

Example . org.eclipse.contribution.junit/plugin.xml

<plugin
  ...
  name="%pluginName"
  ...">
  <extension-point id="listeners" name="%testListeners"/>
  <extension point="org.eclipse.ui.propertyPages">
    <page...
     name="%propertyPageName"
    </page>
  </extension>
  ...
</plugin>

The manifest file feature.xml describing a feature includes externalizable strings similar to the plugin.xml. The conventions to externalize these strings are the same as for the plugin.xml. The look-aside file for the feature.xml is named feature.properties.

Externalizing Strings from Code

Eclipse uses the standard Java resource bundle mechanism to externalize strings. The subpackages of org.eclipse.ui.views serve as good examples to illustrate the conventions:

  • Introduce a resource bundle for each major component in a plug-in. In the case of org.eclipse.views, the components are the different views provided by the plug-in. Having a separate bundle for each component simplifies the bundle management and avoids having to merge conflicting changes when working in a team.

  • For each resource bundle, add a properties file, for example, messages.properties, with the externalized strings. Use a helper class like BookMarkExplorerMessages in org.eclipse.ui.views.bookmarkexplorer to access the bundle.

  • Use qualified keys to ensure uniqueness, for example, OpenBookmark.text, OpenBookmark.toolTip, OpenBookmark.errorTitle.

Our contributed JUnit plug-in is simple enough that a single resource bundle is sufficient. To extract the strings, we use the string externalization support provided by the Eclipse Java tooling. Source > Find Strings to Externalize finds all the strings that are not yet marked as externalized. Eclipse uses the comment markers to tag externalized strings (//$NON-NLS-1$). The Source > Externalize Strings wizard extracts the strings and can create the bundle accessor class for us, as shown in Figure 28.2.

Externalizing Strings from Code

This is the generated helper class for accessing externalized strings:

Example . org.eclipse.contribution.junit/JUnitMessages

public class JUnitMessages {

  private static final String BUNDLE_NAME=
    "org.eclipse.contribution.junit.JUnitMessages"; //$NON-NLS-1$
  private static final ResourceBundle RESOURCE_BUNDLE=
    ResourceBundle.getBundle(BUNDLE_NAME);

  private JUnitMessages() {
  }
  public static String getString(String key) {
    try {
      return RESOURCE_BUNDLE.getString(key);
    } catch (MissingResourceException e) {
      return '!' + key + '!';
    }
  }
}

Here is an excerpt of code with externalized strings:

Example . org.eclipse.contribution.junit/AutoTestPropertyPage

...
Label label= new Label(composite, SWT.NONE);
label.setText(JUnitMessages.getString(
  "PropertyPage.description"));//$NON-NLS-1$

To verify that you have externalized all strings, you might want to turn on the Usage of non-externalized strings Java compiler option (Window > Preferences > Java > Compiler).

One problem with internationalization is you don't want to wait to ship your plug-ins until all the translations are ready. To ship translations separately, Eclipse provides fragments. A fragment allows you to add code or resources to an existing plug-in. Once the translations are ready, you can package them up into a fragment that extends your base plug-in.

Accessibility

While you externalize strings, it's a good time to give attention to accessibility issues. The primary accessibility issues you need to address in your plug-in are:

  • Keyboard access—Every action in the plug-in's UI needs to be accessible via the keyboard.

  • Object information—Enable screen readers. Associate labels with controls. Information contained in images should also be available as text.

  • Display/sound—Use color as an enhancement only. Support high contrast settings. Provide accessible alternatives for significant audio and video content.

In this chapter we will only touch on keyboard access and screen readers. The forward pointers contain guidelines for using color and sound.

An important requirement for an accessible application is that everything in an application can be reached with the keyboard. To make menu items and widgets in dialogs more easily accessible, we assign them mnemonics. This is done in both the plugin.xml and the code by prefixing the mnemonic letter with a “&”. A mnemonic is shown with a letter underlined in menus and dialogs. When pressing the mnemonic letter, the selection or focus will jump to this item.

Currently, none of our menu items and dialog items has a mnemonic. We should try hard to come up with unique mnemonic letter choices. Since Eclipse menus are extensible, collisions can happen. The only consequence of a collision is that the user will have to press the mnemonic letter more than once. The object contribution to run a test and the auto test label in the property page both need a mnemonic, as shown in Figure 28.3.

Display/sound—

Example . org.eclipse.contribution.junit/plugin.properties

pluginName=Contributed Junit Plug-in
testListeners=Test Listeners
propertyPageName=Auto-test
runTestLabel=Run &Test
resultViewName=Contributed Result View
...

If you want to test whether your plug-in is accessible from the keyboard, use it while your mouse is unplugged.

Accessibility goes further than just defining mnemonics. For example, another requirement is that you have to accommodate screen readers. A screen reader can read the contents of widgets aloud. For example, our existing ResultView doesn't address this requirement. It only shows a red/green/grey color indication of a test's status. To make the view accessible, the color indication has to include some textual label like OK, Failed, Unknown.

In this chapter we have made our plug-in internationalized and accessible.

  • Externalized strings

  • Added mnemonics

The final bit of work on our plug-in in the next chapter is to explicitly publish its API.

Forward Pointers

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset