17. Mobile Internationalization

MOBILE internationalization is a fancy phrase that means making your application run in different langauges. Localization is the process of creating phrases, images, and other resources for a specific language. Internationalization (abbreviated i18n) is what you do to your application so that it can be localized easily.

The Mobile Internationalization API (MIA) is defined by JSR 238, and it includes four elements:

  1. A ResourceManager provides the plumbing your application needs to retrieve resource strings, images, and other objects.

  2. The MIA specification also defines a resource file format that describes how localized resources are stored.

  3. Formatter knows how to represent numbers, currency, dates, and times in a specific language or region.

  4. StringComparator understands how to sort strings according to the rules for a particular language.

MIA is relatively compact and resides in the javax.microedition.global package.

17.1. About Locales

Resources are based on locales, which are combinations of a language and a country or region. A locale, in essence, is a language, but it can be made more specific by adding a country as well. This makes sense because the same language is used differently in different parts of the world. Spanish in Mexico, for example, is different from Spanish in Spain.

Languages are represented using two-letter codes as defined by ISO 639. A list is here:

http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt

Countries are represented using two-letter codes defined by ISO 3166. The list of country codes is here:

http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.html

A locale code is simply a language code, a hyphen, and a country code. For example, en-US represents English in the United States of America.

The system property microedition-locale contains the default locale code for a device. It is allowed to be null, in which case you must fall back on appropriate default behavior.

17.2. Using Resources

In the absence of MIA, you might create a simple user interface like this:

Image

This little code snippet contains three hardcoded strings. Let’s assume that “ApplicationName” will be shown regardless of the language of the rest of the user interface. The other two strings should be retrieved from a resource file so that they can easily be localized.

A resource file is represented by ResourceManager. ResourceManager contains strings and byte arrays, each of which has an identification (ID) number. You can retrieve a resource from ResourceManager by passing the ID to get() or getString(). A globalized version of the previous example looks like this:

Image

It’s good practice to use static final constants for resource IDs instead of embedding the numbers directly in your code. Here is an even more correct version:

Image

17.3. Finding Resources

To load a resource file, pass a base name to one of ResourceManager’s static getManager() factory methods. ResourceManager attempts to use the default locale (from the microedition.locale system property) if you don’t specify a locale. If you do, you can pass either a single locale or an array of locales.

Resource files are stored in a binary format in the MIDlet suite JAR file. They are located under the global directory. The location and format of resource files is defined in the JSR 238 specification. You should not have to know the details, because developer tools that support MIA include some kind of resource editor.

In general, resource files have the same base name and are located in directories that are named for locales.

In the Sun Java Wireless Toolkit, navigate to the resource editor (Figure 17.1) by choosing File > Utilities from the KToolbar menu, then selecting i18n Resources Manager and pressing Launch. Select your project from the Projects combo box and you are ready to edit resources. See the documentation for more details.

Figure 17.1. The Sun Java Wireless Toolkit’s resource editor

Image

In NetBeans, choose Tools > Java Platform Manager from the menu. Select the Sun Java Wireless Toolkit from the list of platforms. Click on the Tools & Extensions tab, then press Open Utilities. Select i18n Resources Manager and press Launch.

The example at the end of this chapter shows a resource file with the base name “Babble,” which is defined at the top level (right under global) and for the en-US and de-DE locales. The contents of the de-DE resource file are shown in the bottom part of the window. You can see the IDs and the corresponding resource. All of them are strings except for 3, which is an image byte array.

Typically, your application will attempt to load resources for the device’s locale with code like this:

Image

It is possible that microedition.locale is null. ResourceManager will throw an exception if the requested locale is null, so this example tests for the condition and assigns an empty string if needed. The empty string will at least match the default resource file for the given base name.

17.4. Resource Inheritance

ResourceManager tries hard to honor requests for resources. This commitment to customer service begins at the call to getManager(). ResourceManager attempts to find a resource file that exactly matches the locale you request (or the default locale if you did not specify one).

If an exact match cannot be found, ResourceManager will try to find a resource file that matches just the language part of the locale. If it can’t find that, it will see if there is a default resource file, one with no associated locale, located at the root of the global directory.

Supplying a default resource file is therefore a very good idea, because it allows your application to function even when a resource file matching the requested locale does not exist.

Once you have an appropriate ResourceManager, another inheritance scheme takes effect. Let’s say, for example, that you’ve obtained a ResourceManager for en-US and you request string resource 2. If the resource does not exist, ResourceManager will look for it in an en resource file (if it is available) or the default resource file.

To support both British and American English, then, you could create an en resource file that contains most of the phrases and resources for your application. Then you could also create an en-US resource file with all the Americanisms and an en-GB resource file with the specifically British resources.

The example at the end of this chapter demonstrates this technique. The default resource file contains phrases in English. The en-US resource file contains an image of the American flag but does not define any of the phrases. When the application attempts to retrieve the phrases from the en-US ResourceManager, they are returned from the default resource file.

17.5. Formatting Numbers and Dates

A separate class in MIA, Formatter, knows how to format numbers, currency, dates, times, and percentages in different locales.

To get a Formatter, just pass a locale to its constructor. If an appropriate Formatter does not exist, an UnsupportedLocaleException is thrown. You can also use the Formatter constructor with no arguments, which attempts to use microedition.locale. Finally, if you pass null for the locale, you’ll get a Formatter that works in a locale-neutral way.

The actual formatting is straightforward. Use the formatCurrency() methods for money, the formatNumber() methods for numbers, and formatPercentage() for percentages.


Note

Image

Using floating-point variables for currency is asking for trouble, but MIA embraces it. A safer approach is to use an int or long to store pennies (or the equivalent). Consult the following sources for more information.

Representing money

http://www.javapractices.com/Topic13.cjp

Beware of floating-point numbers

http://www.javapractices.com/Topic213.cjp

Working with money in Java

http://www.javaranch.com/newsletter/July2003/MoneyInJava.html

Currency

http://mindprod.com/jgloss/currency.html

Floating Point

http://mindprod.com/jgloss/floatingpoint.html


The formatDate() method can create a variety of date and time styles. Pass in a java.util.Calendar and one of the style constants from Formatter, either DATE_LONG, DATE_SHORT, TIME_LONG, TIME_SHORT, DATETIME_LONG, or DATETIME_ SHORT.

The trickiest method in Formatter is formatMessage(), which is useful for inserting parameters into a fixed message. For example, you might want to localize the message “You now have n points.” The key is to put the parameters in curly braces. In this example, you could create a string resource like this:

Image

The parameters should be numbered starting from 0 and counting up. You can use as many as 100 parameters in a message. When you want to show the message, pass the message and a string array of parameters to Formatter’s formatMessage() method.

It looks something like this:

Image

17.6. Sorting Strings

Different languages have different alphabets and their own rules about how strings should be sorted (alphabetized). MIA’s StringComparator encapsulates these rules for a locale.

To use StringComparator, pass a locale to its constructor. To compare two strings, pass them to the compare() method. The method returns a negative number if the strings are already in ascending alphabetical order, a positive number if they are in descending order, and zero if the two strings are identical.

You can use StringComparator to sort a list of strings in a manner that is appropriate for a particular locale.

The Sun Java Wireless Toolkit includes a demonstration of this technique. In the i18nDemo project, take a look at the String Comparator example. It shows a list of cities. Choose the Sort - default command to sort the cities using default rules. Now choose Sort - slovak and notice how the sorting changes.

17.7. Take It Out for a Spin

BabbleMIDlet includes examples of most of the techniques you’ve been reading about. It will be useful to you if you are writing an internationalized application. It shows how to retrieve a ResourceManager, how to obtain a Formatter, and how to use both.

Image

Image

Image

Image

Run it with the emulator’s locale as en-US, and the result will look like Figure 17.2.

Figure 17.2. BabbleMIDlet in en-US

Image

The flag image comes from the en-US resource file, while the text phrases are inherited from the default resource file. The Formatter knows about American dollars and successfully formats the points value by inserting a comma.

To really appreciate the talents of this application, you need to change the default locale (the microedition.locale system property) for the emulator. In the Sun Java Wireless Toolkit, choose Edit > Preferences… from the KToolbar menu and click on the i18n category.

In NetBeans, choose Tools > Java Platform Manager from the menu. Select the Sun Java Wireless Toolkit from the list of platforms. Click on the Tools & Extensions tab, then press Open Preferences. Click on the i18n category.

Fill in de-DE for the locale and run BabbleMIDlet again (see Figure 17.3).

Figure 17.3. BabbleMIDlet in de-DE

Image

As you can see, the text phrases and the flag image come from the de-DE resource file. However, the toolkit’s emulator does not include an appropriate formatter. Default behavior, produced from new Formatter(null), occurs instead. The date, time, currency, and number formatting are all plain vanilla, locale-neutral.

For another perspective, try cs-CZ, shown in Figure 17.4.

Figure 17.4. BabbleMIDlet in cs-CZ

Image

This time, no appropriate resource file is available, so all the text prompts come from the default resource file, and the image is not defined at all. Notice how the code in buildForm() catches the ResourceException and will not attempt to add the flag image when it is not available.

However, an appropriate Formatter is available on the toolkit’s emulator. The date, time, currency, and number formatting are correct for cs-CZ, even though the phrases have all been pulled from the default resource file.

17.8. Summary

The Mobile Internationalization API provides the plumbing you need to make applications that can run smoothly in different languages. It defines a scheme for resource files, represented by ResourceManager, which contain phrases and other data. A resource file belongs to a locale, which is a combination of a language and a country. Resource information can be inherited from less specific resource files, including the default. A separate class, Formatter, can format dates, currency, and numbers for a locale. Finally, StringComparator encapsulates string sorting functionality for a locale.

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

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