|
When localizing an application, you'll probably have a dauntingly large number of message strings, button labels, and so on, that all need to be translated. To make this task feasible, you'll want to define the message strings in an external location, usually called a resource. The person carrying out the translation can then simply edit the resource files without having to touch the source code of the program. In Java, you use property files to specify string resources, and you implement classes for resources of other types. NOTE
NOTE
Locating Resource BundlesWhen localizing an application, you produce a set of resource bundles. Each bundle is a property file or a class that describes locale-specific items (such as messages, labels, and so on). For each bundle, you provide versions for all locales that you want to support. You need to use a specific naming convention for these bundles. For example, resources specific for Germany go to a file bundleName_de_DE, while those that are shared by all German-speaking countries go into bundleName_de. In general, use
for all country-specific resources, and use
for all language-specific resources. Finally, as a fallback, you can put defaults into a file without any suffix. You load a bundle with the command
The getBundle method attempts to load the bundle that matches the current locale by language, country, and variant. If it is not successful, then the variant, country, and language are dropped in turn. Then the same search is applied to the default locale, and finally, the default bundle file is consulted. If even that attempt fails, the method throws a MissingResourceException. That is, the getBundle method tries to load one of the following bundles until it is successful.
Once the getBundle method has located a bundle, say, bundleName_de_DE, it will still keep looking for bundleName_de and bundleName. If these bundles exist, they become the parents of the bundleName_de_DE bundle in a resource hierarchy. Later, when looking up a resource, the parents are searched if a lookup was not successful in the current bundle. That is, if a particular resource was not found in bundleName_de_DE, then the bundleName_de and bundleName will be queried as well. This is clearly a very useful service and one that would be tedious to program by hand. The resource bundle mechanism of the Java programming language automatically locates the items that are the best match for a given locale. It is easy to add more and more localizations to an existing program: All you have to do is add additional resource bundles. TIP
Property FilesInternationalizing strings is quite straightforward. You place all your strings into a property file such as MyProgramStrings.properties. This is simply a text file with one key/value pair per line. A typical file would look like this: computeButton=Rechnen colorName=black defaultPaperSize=210x297 Then you name your property files as described in the preceding section, for example: MyProgramStrings.properties MyProgramStrings_en.properties MyProgramStrings_de_DE.properties You can load the bundle simply as ResourceBundle bundle = ResourceBundle.getBundle("MyProgramStrings", locale); To look up a specific string, call String computeButtonLabel = bundle.getString("computeButton"); CAUTION
Bundle ClassesIn order to provide resources that are not strings, you define classes that extend the ResourceBundle class. You use the standard naming convention to name your classes, for example MyProgramResources.java MyProgramResources_en.java MyProgramResources_de_DE.java You load the class with the same getBundle method that you use to load a property file: ResourceBundle bundle = ResourceBundle.getBundle("MyProgramResources", locale); CAUTION
Each resource bundle class implements a lookup table. You provide a key string for each setting you want to localize, and you use that key string to retrieve the setting. For example, Color backgroundColor = (Color) bundle.getObject("backgroundColor"); double[] paperSize = (double[]) bundle.getObject("defaultPaperSize"); The simplest way of implementing resource bundle classes is to extend the ListResourceBundle class. The ListResourceBundle lets you place all your resources into an object array and then does the lookup for you. Follow this code outline:
For example, public class ProgramResources_de extends ListResourceBundle { public Object[][] getContents() { return contents; } private static final Object[][] contents = { { "backgroundColor", Color.black }, { "defaultPaperSize", new double[] { 210, 297 } } } } public class ProgramResources_en_US extends ListResourceBundle { public Object[][] getContents() { return contents; } private static final Object[][] contents = { { "backgroundColor", Color.blue }, { "defaultPaperSize", new double[] { 216, 279 } } } } NOTE
Alternatively, your resource bundle classes can extend the ResourceBundle class. Then you need to implement two methods, to enumerate all keys and to look up the value for a given key: Enumeration<String> getKeys() Object handleGetObject(String key) The getObject method of the ResourceBundle class calls the handleGetObject method that you supply. java.util.ResourceBundle 1.1
|
|