| Writing Global Programs

## What Are Locales and How Do I Use Them?

> In JDK 1.1, a Locale object 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 French Canada. 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:

> >     private Locale supportedLocales[] = {
> >         Locale.US,
> >         Locale.FRANCE,
> >         Locale.CANADA_FRENCH
> >     };

> 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 French Canada--and uses three of the Locale class's convenient constants to create them.

> The construct `Locale.US` is equivalent to:

> >     new Locale("en", "US");

> This particular Locale constructor requires two arguments: The language code and the country code for the Locale that you want to create.

> 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.txt

> The 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.html

> The 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:

> 1. get information from it about the locale
> 2. 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:

> > >     cards.add(supportedLocales[i].getDisplayName(), linguaPanel);

> > The CardLayout layout manager uses this name to show the correct LinguaPanel based on the currently selected locale:

> > >     ((CardLayout)cards.getLayout()).show(cards, currentLocale.getDisplayName());

> > This form of `getDisplayName` returns the name of the locale in the language of application's default locale. The Locale class provides a locale-sensitive version of `getDisplayName` which the LinguaPanel uses to display the name of the currently selected locale to the user in the language of the currently selected locale:

> > >     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:

> > >     // 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], inAnApplet,
> > >                                       defaultFont, boldFont, soundImages, soundNames);
> > >             } catch (java.util.MissingResourceException e) {
> > >                 System.out.println("Couldn't load resource(s).");
> > >             }

> > >             // add it to the card layout
> > >             cards.add(supportedLocales[i].getDisplayName(), linguaPanel);
> > >         }

> > >     // add the card layout to this window
> > >         add("Center", cards);

> > This code snippet steps through the `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 locale-sensitive operation the LinguaPanel constructor does is 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-Senitive 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 Formatting and Parsing.

| Writing Global Programs