THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

convenience.


The following example shows an internationalized way to rewrite the "Hello, world" example. This
internationalized version requires a program called GlobalHello and a resource bundle for the program's
strings called GlobalRes, which will define a set of constants for the localizable strings. First, the program:


import java.util.*;


public class GlobalHello {
public static void main(String[] args) {
ResourceBundle res =
ResourceBundle.getBundle("GlobalRes");
String msg;
if (args.length > 0)
msg = res.getString(GlobalRes.GOODBYE);
else
msg = res.getString(GlobalRes.HELLO);
System.out.println(msg);
}
}


The program first gets its resource bundle. Then it checks whether any arguments are provided on the
command line. If some are, it says good-bye; otherwise it says hello. The program logic determines which
message to display, but the actual string to print is looked up by key (GlobalRes.HELLO or
GlobalRes.GOODBYE).


Each resource bundle is a set of associated classes and property files. In our example, GlobalRes is the
name of a class that extends ResourceBundle, implementing the methods necessary to map a message key
to a localized translation of that message. You define classes for the various locales for which you want to
localize the messages, naming the classes to reflect the locale. For example, the bundle class that manages
GlobalRes messages for the Lingala language would be GlobalRes_ln because "ln" is the two-letter
code for Lingala. French would be mapped in GlobalRes_fr, and Canadian French would be
GlobalRes_fr_CA, which might have a parent bundle of GlobalRes_fr.


We have chosen to make the key strings constants in the GlobalRes class. Using constants prevents errors
of misspelling. If you pass literal strings such as "hello" to getString, a misspelling will show up only
when the erroneous getString is executed, and that might not happen during testing. If you use constants,
a misspelling will be caught by the compiler (unless you are unlucky enough to accidentally spell the name of
another constant).


You find resources by calling one of two static getBundle methods in ResourceBundle: the one we
used, which searches the current locale for the best available version of the bundle you name; and the other
method, which lets you specify both bundle name and desired locale. A fully qualified bundle name has the
form package.Bundle_la_CO_va, where package.Bundle is the general fully qualified name for
the bundle class (such as GlobalRes), la is the two-letter language code (lowercase), CO is the two-letter
country code (uppercase), and va is the list of variants separated by underscores. If a bundle with the full
name cannot be found, the last component is dropped and the search is repeated with this shorter name. This
process is repeated until only the last locale modifier is left. If even this search fails and if you invoked
getBundle with a specified locale, the search is restarted with the full name of the bundle for the default
locale. If this second search ends with no bundle found or if you were searching in the default locale,
getBundle checks using just the bundle name. If even that bundle does not exist, getBundle throws a
MissingBundleException.


For example, suppose you ask for the bundle GlobalRes, specifying a locale for an Esperanto speaker
living in Kiribati who is left-handed, and the default locale of the user is for a Nepali speaker in Bhutan who

Free download pdf