All Packages Class Hierarchy This Package Previous Next Index
java.lang.Object | +----java.util.ResourceBundle
String
for example, your program can load it from the resource bundle that is appropriate for the current user's locale. In this way, you can write program code that is largely independent of the user's locale isolating most, if not all, of the locale-specific information in resource bundles. This allows you to write programs that can:
One resource bundle is, conceptually, a set of related classes that inherit from ResourceBundle
. Each related subclass of ResourceBundle
has the same base name plus an additional component that identifies its locale. For example, suppose your resource bundle is named MyResources
. The first class you are likely to write is the default resource bundle which simply has the same name as its family--MyResources
. You can also provide as many related locale-specific classes as you need: for example, perhaps you would provide a German one named MyResources_de
.
Each related subclass of ResourceBundle
contains the same items, but the items have been translated for the locale represented by that ResourceBundle
subclass. For example, both MyResources
and MyResources_de
may have a String
that's used on a button for confirming operations. In MyResources
the String
may contain OK
and in MyResources_de
it may contain Gut
.
If there are different resources for different countries, you can make specializations: for example, MyResources_de_CH
for Switzerland. If you want to only modify some of the resources in the specialization, you can do so.
When your program needs a locale-specific object, it loads the ResourceBundle
class using the getBundle
method:
The first argument specifies the family name of the resource bundle that contains the object in question. The second argument indicates the desired locale.ResourceBundle myResources = ResourceBundle.getBundle("MyResources", currentLocale);
getBundle
uses these two arguments to construct the name of the ResourceBundle
subclass it should load as follows. The resource bundle lookup searches for classes with various suffixes on the basis of (1) the desired locale and (2) the default locale (baseclass), in the following order from lower-level (more specific) to parent-level (less specific):
baseclass + "_" + language1 + "_" + country1 + "_" + variant1
baseclass + "_" + language1 + "_" + country1
baseclass + "_" + language1
baseclass
baseclass + "_" + language2 + "_" + country2 + "_" + variant2
baseclass + "_" + language2 + "_" + country2
baseclass + "_" + language2
The result of the lookup is a class, but that class may be backed by a property file on disk. If a lookup fails, getBundle()
throws a MissingResourceException
.
The baseclass must be fully qualified (for example, myPackage.MyResources
, not just MyResources
). It must also be accessable by your code; it cannot be a class that is private to the package where ResourceBundle.getBundle
is called.
Note: ResourceBundle
are used internally in accessing NumberFormat
s, Collation
s, and so on. The lookup strategy is the same.
Resource bundles contain key/value pairs. The keys uniquely identify a locale-specific object in the bundle. Here's an example of a ListResourceBundle
that contains two key/value pairs:
Keys are alwaysclass MyResource extends ListResourceBundle { public Object[][] getContents() { return contents; } static final Object[][] contents = { // LOCALIZE THIS {"OkKey", "OK"}, {"CancelKey", "Cancel"}, // END OF MATERIAL TO LOCALIZE }; }
String
s. In this example, the keys are OkKey
and CancelKey
. In the above example, the values are also String
s--OK
and Cancel
--but they don't have to be. The values can be any type of object. You retrieve an object from resource bundle using the appropriate getter method. Because OkKey
and CancelKey
are both strings, you would use getString
to retrieve them:
The getter methods all require the key as an argument and return the object if found. If the object is not found, the getter method throws abutton1 = new Button(myResourceBundle.getString("OkKey")); button2 = new Button(myResourceBundle.getString("CancelKey"));
MissingResourceException
. Besides getString
; ResourceBundle supports a number of other methods for getting different types of objects such as getStringArray
. If you don't have an object that matches one of these methods, you can use getObject
and cast the result to the appropriate type. For example:
int[] myIntegers = (int[]) myResources.getObject("intList");
NOTE: You should always supply a baseclass with no suffixes. This will be the class of "last resort", if a locale is requested that does not exist. For example, below we have a class MyResources
. It happens to contain US strings, so we don't have to have an explicit MyResource_en
or MyResource_en_US
.
The JDK provides two subclasses of ResourceBundle
, ListResourceBundle
and PropertyResourceBundle
, that provide a fairly simple way to create resources. (Once serialization is fully integrated, we will provide another way.) As you saw briefly in a prevous example, ListResourceBundle
manages its resource as a List of key/value pairs. PropertyResourceBundle
uses a properties file to manage its resources.
If ListResourceBundle
or PropertyResourceBundle
do not suit your needs, you can write your own ResourceBundle
subclass. Your subclasses must overrde two methods: handleGetObject
and getKeys()
.
The following is a very simple example of a Example:ResourceBundle
subclass that manages only a few resources (for a larger number of resources you would probably use a Hashtable
). Notice that if the key is not found, handleGetObject
must return null. Notice also that you don't need to supply a value if a "parent-level" ResourceBundle
handles the same key with the same value (look at uk below).
You do not have to restrict yourself to using a single family ofabstract class MyResources extends ResourceBundle { public Object handleGetObject(String key) { if (key.equals("okKey")) return "Ok"; if (key.equals("cancelKey")) return "Cancel"; return null; } } abstract class MyResources_de extends MyResources { public Object handleGetObject(String key) { if (key.equals("okKey")) return "Gut"; if (key.equals("cancelKey")) return "Vernichten"; return null; } } abstract class MyResources_uk extends MyResources { public Object handleGetObject(String key) { // don't need okKey, since parent level handles it. if (key.equals("cancelKey")) return "Dispose"; return null; } }
ResourceBundle
s. For example, you could have a set of bundles for exception messages, ExceptionResources
(ExceptionResources_fr
, ExceptionResources_de
, ...), and one for widgets, WidgetResource
(WidgetResources_fr
, WidgetResources_de
, ...); breaking up the resources however you like. protected ResourceBundle parent
public ResourceBundle()
public final String getString(String key) throws MissingResourceException
public final String[] getStringArray(String key) throws MissingResourceException
public final Object getObject(String key) throws MissingResourceException
public static final ResourceBundle getBundle(String baseName) throws MissingResourceException
public static final ResourceBundle getBundle(String baseName, Locale locale)
protected void setParent(ResourceBundle parent)
protected abstract Object handleGetObject(String key) throws MissingResourceException
public abstract Enumeration getKeys()
All Packages Class Hierarchy This Package Previous Next Index