Localize this!
Use resource bundles to make your applications multicultural
By Todd Sundsted, JavaWorld.com, 01/01/98
- Digg
- Reddit
- SlashDot
- Stumble
- del.icio.us
- Technorati
- dzone
For you to better understand how we're going to internationalize our application's text, including button labels, label text,
and error messages, we need to look closely at what went on last month. Here's what happened from the application's point
of view:
- The application started with a piece of data, such as an instance of the
Date class, stored in some locale-neutral form.
- The application created an instance of the proper formatter, such as
DateFormat, from the java.text package.
- Behind the scenes, the application queried the runtime in order to determine the locale in which the application was running.
This likely involved some interaction with the operating system.
- Based on the information it received, the application determined how to format the date for the locale, given that the locale
was supported.
- The application then formatted the date and created a string.
- Finally, the application displayed the string.
Steps 3 through 5 were hidden from view. The DateFormat and the NumberFormat classes did the work behind the scenes. (If you'd like more detailed information, take a look at last month's column.) This month, let's take a closer look at step 4.
Because the programmers at Sun wrote the code for the DateFormat and the NumberFormat classes, they were responsible for deciding which locales to support and for providing the code to perform the appropriate
data conversions for those particular locales. Because there are only so many variations on dates and numbers, they were able
to build the necessary code for formatting data in the Number and Date classes, according to the appropriate locale, directly into the Java library.
That saved us a lot of work!
Unfortunately, such forward planning and implementation isn't quite so easy when it comes to text messages. The developers
at Sun could not possibly anticipate all the different text messages used by each application (current and future) and provide
the appropriate translations; they left that task to individual developers. It is, therefore, up to us to decide which locales
we intend to support and provide translations of our messages for each. In short, the work for step 4 now falls squarely on
our shoulders.
Locale
Before we can proceed, we really need to better understand the notion of a locale, and its associated Java class
Locale.
A locale is a loose term for a specific geographical, political, or cultural region. It's best defined by example. The region
of origin of a group of people can often be surmised by the language they speak. Therefore, as you might also guess, language
is an important component of locale. So too is nationality. Even though Americans and the British share a common tongue, we
each possess our own customs and cultural identity. Thus, each region is its own locale.
In the Java programming language, a locale is represented by an instance of class Locale. An instance of Locale can be created for any language and any country. The Locale class also provides several predefined values for common countries (US and CANADA, for example) and languages (ENGLISH and FRENCH for example).
Operations that can be localized (formatting a date, for example) usually take a Locale instance as an argument. If it is not specified, the argument defaults to the current locale.
Resource bundles
Now let's return to our problem.
To completely internationalize our application, we'll need to gather a collection of strings appropriate for a locale and
use them in appropriate places throughout the application. In order to assist us, the Java class library provides resource
bundles.
A resource bundle is a collection of all resources and information for a specific locale. It associates each resource with
a key, and the key is the same for each particular resource across all locales. In addition, due to the way resource bundles
are named (explained below), they provide an orderly, effective way of locating the correct resource bundle.
Let's take a look at a concrete example. Recall that last month's example had five buttons: previous, next, new, add, and
delete.

The Record Manager buttons
Each button has a label that indicates its function. Obviously, the labels should be in the appropriate language for the current
locale. Therefore, for each locale I plan to support, I create a resource bundle containing the labels of each button, appropriately
translated. Each resource bundle has five key/value pairs. The keys are the same across all bundles, while the values change
to suit the locale. A key can hold any string. It is usually something significant to the programmer ("btn1," "btnPrevious,"
or "previous").
Consider the button bundle for my locale (the United States of America). The following table shows the keys and values for
this bundle.
Bundles and bundles of fun
A set of bundles (all the bundles that hold labels for the buttons in our application, for example) all belong to a group.
The group has a name, often referred to as the "bundle name." Likewise, each bundle in the group of bundles has a name. The
names are constructed in a uniform fashion: the bundle name plus the language, the country (optional), and the variant (a
variant is a subregion within a country -- it's optional as well). One bundle has the same name as the group itself. This
is the default bundle, and is the one selected if no other bundle is more appropriate.
This naming scheme is not as difficult as it sounds, but I think an example will help. Assume we have a group of bundles that
hold the labels of the buttons in our application. The bundle name of the group is something like "ButtonLabels." At the very
least, there would be one bundle -- the one with the name "ButtonLabels." If there was a specific bundle holding labels for
francophones (French speakers), it would be named "ButtonLabels_fr" (note the underscore). If there was a specific bundle
holding labels for French speaking Canadians, it would be named "ButtonLabels_fr_CA". I'll explain what the two letter abbreviations
mean and how they're used in a moment. Likewise, for those who speak Japanese, "ButtonLabels_JP". If there was a specific
bundle holding labels for the English speakers of Great Britain, it would be named "ButtonLabels_en_GB".
- Digg
- Reddit
- SlashDot
- Stumble
- del.icio.us
- Technorati
- dzone
Resources
- The internationalization specification http://java.sun.com/products/JDK/1.1/intl/html/intlspecTOC.doc.html
- The Locale class http://www.javasoft.com/products/jdk/1.1/docs/api/java.util.Locale.html
- The ResourceBundle class http://www.javasoft.com/products/jdk/1.1/docs/api/java.util.ResourceBundle.html
- The ListResourceBundle class http://www.javasoft.com/products/jdk/1.1/docs/api/java.util.ListResourceBundle.html
- The PropertyResourceBunlde class http://www.javasoft.com/products/jdk/1.1/docs/api/java.util.PropertyResourceBundle.html
- ISO-639 http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt
- ISO-3166 http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html
- Download this article and the complete source as a gzipped tar file /javaworld/jw-01-1998/howto/jw-01-howto.tar.gz
- Download this article and the complete source as a zip file /javaworld/jw-01-1998/howto/jw-01-howto.zip
- Previous How-To Java articles
- "Write world-class applications" From Chicago to Copenhagen, Colombia to Cameroon -- Java provides the tools for writing truly international applications.
- "Use the two "R"s of Java 1.1 -- Readers and Writers" Learn how to use the two new additions to the
java.io package -- class Reader and class Writer -- to filter out unwanted e-mail.
- "Waging war on electronic junk mail" Put Java on the front line in the war against electronic junk mail.
- "Build dynamically extensible applications" Find out how to build programs that you can extend dynamically -- even while they execute.
- "3D computer graphicsGetting the hang of VRML" Learn about VRML and how you can use it to define your own virtual world.
- "3D computer graphicsMoving from wire-frame drawings to solid, shaded models" Find out how to create surfaces and add illumination to make your models more realistic.
- "3D computer graphicsSlide it, spin it, make it move -- transforming your virtual world" Learn how to make your virtual world satisfy even the toughest customer.
- "3D computer graphicsModel your world" From its start as an exotic research topic in government and university labs, virtual reality is making its move into the
mainstream of corporate America -- find out how you can gain entry into this elite club.
- "When static images just don't make the cut" Learn how to spice up your applets and applications with animated images.
- "How Java uses the the producer/consumer model to handle images -- An insider's look" Learn more about Java's powerful image-handling technique, then follow my simple procedures for building your own producer
and consumer components.
- "Learn how applets load network-based images asynchronously" Here's a close look at the way Java applets handle images in a network-based environment.
- "Drawing text is easy with three Java classes" Find out how to create text that's visually appealing through this explanation of what classes to use and how they work
together.
- "Examining HotSpot, an object-oriented drawing program" Learn how the pieces of the Java language and class library fit together through a study of this Java program
- "Using the Graphics class" A close look at the Graphics class and the drawing primitives it provides, and a demonstration of its use.
- "Observer and Observable" An introduction to the Observer interface and Observable class using the Model/View/Controller architecture as a guide.
- "The effective user interface" Five ways to enhance the appearance and effectiveness of your user interface
- "Java and event handling" How events are passed to user interface components, how to create event handlers, and more.
- "Introduction to the AWT" A description of Java's user interface toolkit.