Previous | Next | Trail Map | Internationalization | Isolating Locale-Specific Data

About the ResourceBundle Class

How a ResourceBundle is Related to a Locale

Conceptually, each ResourceBundle is a set of related subclasses that share the same base name. The list that follows shows a set of related subclasses. ButtonLabel is the base name. The characters following the base name indicate the language code, country code, and variant of a Locale. For instance, ButtonLabel_en_GB matches the Locale specified by the language code for English (en) and the country code for the U.K. (GB).
ButtonLabel 
ButtonLabel_de 
ButtonLabel_en_GB 
ButtonLabel_fr_CA_UNIX

To select the appropriate ResourceBundle, you invoke the ResourceBundle.getBundle method. The following example selects the ButtonLabel ResourceBundle for the Locale that matches the French language, the country of Canada, and the UNIX platform.

Locale currentLocale = new Locale("fr", "CA", "UNIX");

ResourceBundle introLabels = 
   ResourceBundle.getBundle("ButtonLabel", currentLocale);

If a ResourceBundle class for the specified Locale does not exist, getBundle tries to find the closest match. For example, if a class for ButtonLabel_fr_CA_UNIX does not exist, getBundle will look for classes in the following order:

ButtonLabel_fr_CA_UNIX
ButtonLabel_fr_CA
ButtonLabel_fr
ButtonLabel
If getBundle fails to find a match in the preceding list of classes, then it will attempt a similar search using the default Locale. Failing there, getBundle will throw a MissingResourceException.

You should always provide a base class with no suffixes. In the previous example, if a class named ButtonLabel exists, then getBundle will not throw a MissingResourceException.

The ListResourceBundle and PropertyResourceBundle Subclasses

The abstract class ResourceBundle has two subclasses: ListResourceBundle and PropertyResourceBundle. The subclass you choose depends on the type of data, and how it is to be localized.

A PropertyResourceBundle is backed by one or more properties files. You should store translatable String objects in properties files. Since the properties files are simple text files and are not part of the Java source code, they can be created and updated by translators. No programming expertise is required. A translator can add support for an additional Locale merely by creating a new properties file. A new class file is not needed. Properties files can contain values for String objects only. If you need to store other types of objects, use a ListResourceBundle instead. Backing a ResourceBundle with Properties Files shows you how to use a PropertyResourceBundle.

The ListResourceBundle class manages resources with a convenient list. Each ListResourceBundle is backed by a class file. You can store any locale-specific object in a ListResourceBundle. To add support for an additional Locale, you must create another source file and compile it into a class file. Since translators are not usually programmers, you should not store String objects that require translation in a ListResourceBundle. Using a ListResourceBundle contains a coding example you may find helpful.

The ResourceBundle class is flexible. If you first loaded your locale-specific String objects in a ListResourceBundle, and then later decided to use PropertyResourceBundle instead, the impact on your code will be limited. For example, the following call to getBundle will retrieve a ResourceBundle for the appropriate Locale, whether ButtonLabel is backed up by a class or by a properties file:

ResourceBundle introLabels = 
   ResourceBundle.getBundle("ButtonLabel", currentLocale);

Key-Value Pairs

ResourceBundle objects contain an array of key-value pairs. You specify the key, which must be a String, when you want to retrieve the value from the ResourceBundle. The value is the locale-specific object. In the following example, the keys are the "OkKey" and "CancelKey" String objects:
class ButtonLabel_en extends ListResourceBundle {
   // English version
   public Object[][] getContents() {
     return contents;
   }
   static final Object[][] contents = {
      {"OkKey", "OK"},
      {"CancelKey", "Cancel"},
   };
}
To retrieve the "OK" String from the ResourceBundle, you would specify the appropriate key when invoking getString:
String okLabel = ButtonLabel.getString("OkKey");
The preceding example is simplistic, because the String values are hardcoded in the source code. This is not good practice, because your translators need to work with properties files which are separate from the source code.

A properties file contains key-value pairs. The key is on the left side of the equals sign and the value is on the right. Each pair is on a separate line. The values may represent String objects only. The following example shows the contents of a properties file named ButtonLabel.properties:

OkKey = OK
CancelKey = Cancel


Previous | Next | Trail Map | Internationalization | Isolating Locale-Specific Data