Locale-Sensitive Data |
A resource bundle is really a set of related classes that inherit from ResourceBundle. These related classes are called a resource bundle family. Each family of resource bundles has the same base name plus an additional component that identifies its locale.One of AroundTheWorld's resource bundle families is the LabelsBundle family. This family of bundles contains the labels used to identify the various data items (Locale Name, Time, Date and so on). Because AroundTheWorld supports three different locales, it requires three different versions of LablesBundle. The first is the default resource bundle which simply has the same name as its family--LabelsBundle. In AroundTheWorld the default LabelsBundle contains the locale-specific information for the United States simply because the author of the program is American. However, any default data will do. In addition to the default LabelsBundle, AroundTheWorld has two more: LabelsBundle_fr, and LabelsBundle_en_UK. The
LabelsBundle
component of the classname identifies these two classes as members of the LabelsBundle family. The_fr
and_en_UK
components of the classname identify the locale._fr
indicates that the data is appropriate for a French speaking locale (any country) and_en_GB
indicates that the data is appropriate specifically for the United Kingdom locale.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 LabelsBundle and LablesBundle_fr have a
LocaleLabel
item. In LabelsBundle theLocaleLabel
item is "Locale:" and inLocaleLabel
item it contains a string awaiting translation.You'll note that the United States and the United Kingdom can share some items (the phrase "Literacy Rate" is the same in both countries) but not others (the representative city for the US is San Francisco but for the UK it's London). In this case, the bundle need only contain specializations for those items that are different (LablesBundle_en_GB only contains the RepCity and TimeZone items).
Along with LabelsBundle, the AroundTheWorld program has three other resource bundle families all loaded by the LinguaPanel class with this code:
Three of the bundles,ResourceBundle labels = ResourceBundle.getBundle("LabelsBundle", locale); ResourceBundle paragraph = ResourceBundle.getBundle("ParagraphBundle", locale); ResourceBundle numbers = ResourceBundle.getBundle("NumbersBundle", locale); ResourceBundle soundBundle = ResourceBundle.getBundle("SoundBundle", locale);LabelsBundle
,NumbersBundle
, andSoundBundle
, are all subclasses ofListResourceBundle
.ParagraphBundle
is aPropertyResourceBundle
. Let's first investigate loading the list resource bundles. We'll look at the properties bundle later.The first argument to
ResourceBundle.getBundle
is the bundle name. This argument must be the fully qualified name of the base resource bundle class. Thus, it must include the full package name as well as the classname:myPackage.MyResources
. Each of AroundTheWorld's resource bundles live in the default package, so in this case, the classname is the fully qualified name for each bundle:LabelsBundle
,NumbersBundle
, andSoundBundle
.Loading a resource bundle via
getBundle
is a locale-sensitive operation. Thus, the second argument togetBundle
is a locale.getBundle
uses this locale object to identify which version of the resource bundle to load.To find the correct, locale-specific, resource bundle,
getBundle
builds variations of the bundle name until it finds the name of a class that can be loaded. The series of names looks like this:wherebundleName + "_" + localeLanguage + "_" + localeCountry + "_" + localeVariant bundleName + "_" + localeLanguage + "_" + localeCountry bundleName + "_" + localeLanguage bundleName + "_" + defaultLanguage + "_" + defaultCountry + "_" + defaultVariant bundleName + "_" + defaultLanguage + "_" + defaultCountry bundleName + "_" + defaultLanguage bundleNamelocaleLanguage
,localeCountry
andlocaleVariant
are taken from the locale specified in thegetBundle
call.defaultLanguage
,defaultCountry
anddefaultVariant
are taken from the default locale. As you can see, the resource bundle namedbundleName
is the bundle of last resort and contains the values to be used if a version of the bundle is not available for a specific locale. If noResourceBundle
subclass can be found,getBundle
throws aMissingResourceException
.Typically, a program provides a default bundle for each of its resource bundles. The default bundle contains the full set of key-value pairs in the bundle. Thus, people performing the localization on the bundle have all the information required.
Let's watch how LabelsBundle is loaded into AroundTheWorld. As you know, AroundTheWorld creates one LinguaPanel per supported locale. Thus, it creates three LinguaPanels, one each for Locale.US, Locale.FRANCE, and Locale.UK. Upon construction each locale-specific LinguaPanel loads a locale-specific version of LabelsBundle.
For example, when AroundTheWorld creates a LinguaPanel for Locale.US,
getBundle
searches first for LabelsBundle_en_US. This search is in vain because there is no LabelsBundle_en_US class. ThengetBundle
searches for LabelsBundle_en (again in vain), and finally it searches for and finds LabelsBundle. The LabelsBundle class is the default bundle and contains English versions of the strings appropriate for the US. Thus it was not necessary to provide another LabelsBundle specifically for the US.
Try this: Figure out how the French and UK LabelsBUndle are loaded. Also look at how the NumbersBundles and SoundBundles are loaded.
If the bundle in question is a properties bundle, such as
ParagraphBundle
in the AroundTheWorld program,getBundle
creates a PropertyResourceBundle and initializes it with the information from a properties file.getBundle
derives the name of the properties file in the same manner as it derives resource bundle class names.To recap: To find the correct, locale-specific, properties file when loading a PropertyResourceBundle,
getBundle
builds variations of the bundle name until it finds the name of a properties file that can be loaded. As with classnames, the series of property filenames looks like this:The properties file has abundleName + "_" + localeLanguage + "_" + localeCountry + "_" + localeVariant bundleName + "_" + localeLanguage + "_" + localeCountry bundleName + "_" + localeLanguage bundleName + "_" + defaultLanguage + "_" + defaultCountry + "_" + defaultVariant bundleName + "_" + defaultLanguage + "_" + defaultCountry bundleName + "_" + defaultLanguage bundleName.properties
extension.When AroundTheWorld creates the LinguaPanel for Locale.US, it searches first for ParagraphBundle_en_US.properties, which it doesn't find, then for ParagraphBundle_en.properties, which again it doesn't find, and then finally for ParagraphBundle.properties, which it does find. As with LabelsBundle, default data is contained in this resource bundle. Because the default contains the information for the United States, a specific US version of this bundle is not necessary.
The French ParagraphBundle properties file is called
ParagraphBundle_fr.properties
. Again, only the values (not the keys) are translated into another language. This properties file is loaded into the PropertyResourceBundle when AroundTheWorld creates the Locale.FRANCE LinguaPanel.The United States and the Untied Kingdom cannot share ParagraphBundles because the paragraph provides a description of the locale. The language that the paragraphs are written in is the same for each locale. However, the contents are different. Thus AroundTheWorld must provide a third file
ParagraphBundle_en_GB.properties
which gets loaded when the program creates the Locale.UK LinguaPanel.
Locale-Sensitive Data |