Previous | Next | Trail Map | Internationalization | Isolating Locale-specific Objects in a ResourceBundle

Backing a ResourceBundle with Properties Files

This section steps through a sample program named PropertiesDemo. The source code for the program is in PropertiesDemo.java. You may also find it helpful to examine the output generated by this program.

1. Create the Default Properties File

A properties file is a simple text file. You can create and maintain a properties file with just about any text editor.

You should always create a default properties file. The name of this file begins with the base name of your ResourceBundle and ends with the .properties suffix. In the PropertiesDemo progam, the base name is LabelsBundle. Therefore, the default properties file is called LabelsBundle.properties. This file contains the following lines:

# This is the default LabelsBundle.properties file
s1 = computer
s2 = disk
s3 = monitor
s4 = keyboard
In the preceeding file, note that comment lines begin with a pound sign (#). The other lines contain key-value pairs. The key is on the left side of the equal sign and the value is on the right. For instance, "s2" is the key that corresponds to the value "disk." The key is arbitrary. We could have called "s2" something else, like "msg5" or "diskID." However, once defined, the key should not change because it is referenced in the source code. The values may be changed. In fact, when your localizers create new properties files to accomodate additional languages, they will translate the values into different languages.

2. Create Additional Properties Files as Needed

To support an addtional Locale, your localizers will create a new properties file that contains the translated values. No changes to your source code are required, because your program references the keys, not the values.

For example, to add support for the German language, your localizers would translate the values in LabelsBundle.properties and place them in a file named LabelsBundle_de_DE.properties. Notice that the name of this file, like that of the default file, begins with the base name LabelsBundle and ends with the .properties suffix. However, since this file is intended for a specific Locale, the base name is followed by the language code (de) and the country code (DE). The contents of LabelsBundle_de_DE.properties is as follows:

# This is the LabelsBundle_de_DE.properties file
s1 = Computer
s2 = Platte
s3 = Monitor
s4 = Tastatur
We've shipped three properties files with the PropertiesDemo sample program:
LabelsBundle.properties
LabelsBundle_de_DE.properties
LabelsBundle_fr.properties

3. Specify the Locale

In the PropertiesDemo program we create the Locale objects as follows:
Locale[] supportedLocales = {
    new Locale("fr","FR"),
    new Locale("de","DE"),
    new Locale("en","US")

Locale currentLocale = new Locale("fr","FR");
For each of these Locale objects we've specified a language code and a country code. These codes will match the properties files we created in the previous two steps. For example, The Locale created with the de and DE codes will match the LabelsBundle_de_DE.properties file.

4. Create the ResourceBundle

This is the step that shows how the Locale the properties files, and the ResourceBundle are related. To create the ResourceBundle, we invoke the getBundle method, specifying the base name and Locale:
ResourceBundle labels =
   ResourceBundle.getBundle("LabelsBundle",currentLocale);
The getBundle method first looks for a class file that matches the base name. If it can't find a class file, it then checks for properties files. In the PropertiesDemo program, we're backing the ResourceBundle with properties files instead of class files. When the getBundle method locates the correct properties file, it returns a PropertyResourceBundle object loaded with the key-value pairs from the properties file.

If a properties file for the specified Locale does not exist, getBundle selects a properties file that is the closest match. The following table identifies the properties file that the PropertiesDemo program selects for each Locale:

Locale Parameters Properties File Loaded Explanation
de   DE
LabelsBundle_de_DE.properties Exact match.
fr   FR
LabelsBundle_fr.properties LabelsBundle_fr_FR.properties does not exist, so
this is the closest match.
en   US
LabelsBundle.properties The default file is selected because the Locale
parameters do not match.

Instead of invoking getBundle, we could have created the PropertyResourceBundle object by invoking its constructor, which accepts an InputStream as an argument. To create the InputStream we must to specify the exact name of the properties file by calling the FileInputStream constructor. Creating a PropertyResourceBundle by invoking getBundle is more flexible, because getBundle will search for the properties file that most closely matches specfied Locale.

5. Fetch the Localized Text

To retrieve the translated value from the ResourceBundle, we invoke the getString method:
String value  = labels.getString(key);
The String returned by getString corresponds to the key we specified. The String is in the proper language, provided that a properties file exists for the specified Locale. Since the keys do not change, the localalizers add additional properties files at a later time. Our call to getString need not change.

6. Iterate Through All the Keys

If you want to fetch values for all of the keys in a ResourceBundle, you need to invoke getKeys. This method returns an Enumeration of all the keys in a ResourceBundle. You can iterate through the Enumeration and fetch each value with the getString method. The following lines code, which are from the PropertiesDemo program, show how this is done:
ResourceBundle labels =
   ResourceBundle.getBundle("LabelsBundle",currentLocale);

Enumeration bundleKeys = labels.getKeys();

while (bundleKeys.hasMoreElements()) {
   String key = (String)bundleKeys.nextElement();
   String value  = labels.getString(key);
   System.out.println("key = " + key + ", " +
     "value = " + value);
}


Previous | Next | Trail Map | Internationalization | Isolating Locale-specific Objects in a ResourceBundle