Locale-Sensitive Data |
In JDK 1.1, a Localeobject represents a specific locale (remember, a locale is a geographic or political region that shares the same language and customs). A Locale object is just an identifier for a region--it does not contain any application-specific data for that region.For example, the AroundTheWorld program uses three Locale objects: one for the United States, one for France, and one for the United Kingdom. These Locale objects do not contain the population, literacy rate, or any other AroundTheWorld specific data. The application-specific data is contained in resource bundles. The program uses a Locale object to identify what the current locale is and to decide which resource bundle to use to construct its display.
Let's take a look at the source code for AroundTheWorld. In particular, let's focus on the code that uses Locale objects. The IntlWindow class defines an array of Locales, called
supportedLocales
, which is created and initialized as follows:This array indicates the number of locales supported by the program and what those locales are. AroundTheWorld currently supports three locales--the United States, France, and the United Kingdom--and uses three of the Locale class's convenient constants to create them.private Locale supportedLocales[] = { Locale.US, Locale.FRANCE, Locale.UK };The construct
Locale.US
is equivalent to:This particular Locale constructor requires two arguments: The language code and the country code for the Locale that you want to create.new Locale("en", "US");The language codes are lower-case, two-letter codes defined by ISO-639. These codes should only be used programmatically. To display the language name to the user, use
getDisplayLanguage
. You can find a full list of language codes at a number of sites, such as: http://www.ics.uci.edu/pub/ietf/http/related/iso639.txtThe country codes are upper-case, two-letter codes defined by ISO-3166. Again, these codes should only be used programmatically. To display the country name to the user, use
getDisplayCountry
. You can find a full list of these codes at a number of sites, such as: http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.htmlThe Locale class has one other constructor that requires three arguments: The language code, the country code as before, and the variant code. For example, the following code snippet creates a California Locale object.
Locale califLocale = new Locale("en", "US", "california");
Note: The JDK does not support a California variant of the United States locale. If you tried to get a number formatter or other similar object for this locale, it will be suitable for the more general United States locale. For information about adding support for your own locales (such as the California locale), see [PENDING].
The variant codes are vendor and browser-specific. Use WIN for Windows, MAC for Macintosh, and POSIX for POSIX. Remember that if the Variant is not found, the more generic version will be used. That is, if you ask for "en", "US", "MAC", and there is no Macintosh version (the code may not even be running on a Macintosh), then "en", "US" will be used. Where there are two variants, separate them with an underscore, and put the most important one first. For example, a Traditional Spanish collation for Windows might be referenced, with "ES", "ES", "Traditional_WIN".
The JDK provides support for the following locales:
Locale Language Country da_DK Danish Denmark de_AT German Austria de_CH German Switzerland de_DE German Germany el_GR Greek Greece en_CA English Canada en_GB English United Kingdom en_IE English Ireland en_US English United States es_ES Spanish Spain fi_FI Finnish Finland fr_BE French Belgium fr_CA French Canada fr_CH French Switzerland fr_FR French France it_CH Italian Switzerland it_IT Italian Italy ja_JP Japanese Japan ko_KR Korean Korea nl_BE Dutch Belgium nl_NL Dutch Netherlands no_NO Norwegian (Nynorsk) Norway no_NO_B Norwegian (Bokmål) Norway pt_PT Portuguese Portugal sv_SE Swedish Sweden tr_TR Turkish Turkey zh_CN Chinese (Simplified) China zh_TW Chinese (Traditional) Taiwan [PENDING: define exactly what supported means]
You can explicitly create a Locale object as shown above or you can get a Locale object from the application or from an AWT Component. When an IntlWindow is first created, it uses its own Locale object to establish which locale is initially selected (and thus which flag is highlighted and which LinguaPanel is displayed):
private int selectedFlag = -1; . . . currentLocale = getLocale(); for (int i = 0; i < supportedLocales.length; i++) { if (currentLocale == supportedLocales[i]) selectedFlag = i; } if (selectedFlag == -1) { currentLocale = supportedLocales[0]; selectedFlag = 0; }Once you've got a Locale object, you can:
- get information from it about the locale
- pass it to other objects that perform Locale-Sensitive Operations
Getting Information from a Locale
The Locale class provides a number of "getter" methods for retrieving information about the locale:getCountry
,getLanguage
,getDisplayLanguage
to name a few.The AroundTheWorld program uses Locale's
getDisplayName
method to provide a unique name for each LinguaPanel to the CardLayout layout manager:The CardLayout layout manager uses this name to show the correct LinguaPanel based on the currently selected locale:cards.add(supportedLocales[i].getDisplayName(), linguaPanel);This form of((CardLayout)cards.getLayout()).show(cards, currentLocale.getDisplayName());getDisplayName
returns the name of the locale in the language of application's default locale. The Locale class provides a locale-sensitive version ofgetDisplayName
which the LinguaPanel uses to display the name of the currently selected locale to the user in the language of the currently selected locale:[PENDING: make it more explicit about why we couldn't use the locale-specific getDisplayName in the first case]localeValue.setText(locale.getDisplayName(locale));Locale-Sensitive Operations
AroundTheWorld uses an array of Locale objects to identify the locales that it supports. The program also uses locales to inform locale-sensitive operations (such as constructing the LinguaPanels, and loading resource bundles) which locale to use.For example, look at the code in IntlWindow that creates the LinguaPanels:
This code snippet steps through the// create a card panel cards = new Panel(); cards.setLayout(new CardLayout()); // create the LinguaPanels that go into the card layout for (int i = 0; i < supportedLocales.length; i ++) { LinguaPanel linguaPanel = null; try { linguaPanel = new LinguaPanel(supportedLocales[i], parentApplet, defaultFont, boldFont, soundImages, soundNames); } catch (java.util.MissingResourceException e) { System.err.println("Couldn't load resource(s)."); System.err.println(e); } // add it to the card layout cards.add(supportedLocales[i].getDisplayName(), linguaPanel); } // add the card layout to this window add("Center", cards);supportedLocales
array and creates one LinguaPanel for each supported locale. Because the creation of a LinguaPanel is locale-sensitive (it displays text and numbers and other language-dependent elements) its constructor requires a Locale object as an argument. What does LinguaPanel do with its Locale object? Let's check it out.The first thing the LinguaPanel constructor does is to load resource bundles based on the locale argument. These resource bundles contain text and numbers specific to the locale. Resource bundles are covered in the next section: Managing Locale-Sensitive Data.
LinguaPanel also uses the Locale object to get date, number, currency and number formatters appropriate for the locale. Formatting is covered along with data parsing in How to Format Numbers, Dates and Times, and Messages.
Locale-Sensitive Data |