![]() ![]() ![]() ![]() |
Locale-Sensitive Data |
A message is any textual information presented to the user. A message could be an error message, or the instructions in an alert box, or the label on a button or other GUI item. Typically, messages are short but they don't have to be.A lot of messages are straightforward text which can simply be stored in a resource bundle and used as-is by the program. Examples of these types of messages are the Locale and Today's Date labels in the
AroundTheWorld
applet. These messages are simple text messages used directly from a resource bundle. Other messages are constructed at runtime and cannot simply be used verbatim from a resource bundle.For example, consider this message from the
AroundTheWorld
program: Current Time (in San Francisco). This message has two parts: the base message and the city. Each part of the message is dependent on the user's locale but in different ways. The base message depends on the locale's language--that is, the base message changes when the language changes but not when the country changes. So, locales with the same language such asen_GB
and theen_US
can share the base message. However, the city depends on the locale's country--that is, the city changes when the country changes soen_GB
anden_US
cannot share the city portion of the message. Thus the message must be constructed at runtime and cannot be used directly from a resource bundle.Other messages must also be constructed at runtime but for reasons other than differences in locale. For example, the italic parts of the following message are dependent on the user's runtime:
You are running JDK 1.1 on Solaris.You might be tempted to construct messages like the two described above using String concatenation and partial text items from resource bundles:However, this approach introduces language dependencies into your program because the word order in different languages is different. So while this may work in English, it probably won't work in French, and German, and certainly won't work in Japanese, Russian and other languages that use a completely different writing system. Instead you should format messages using the JDK 1.1's MessageFormatString version = getVersion(); String system = getSystem(); String msg = myBundle.getString("Running") + version + myBundle.getString("On") + system ;class.
Use
MessageFormat
to construct sequences of strings, numbers, dates, and other formats to create messages. This class facilitates localization because it prevents both hard-coding of message strings, and hard-coding of the concatenation sequence for portions of message strings. This means localizers can change the content, format, and order of any text as appropriate for any language.Here's how the
AroundTheWorld
applet usesMessageFormat
to format the Current Time label:The first line creates an array of objects and puts one item in the array: the string containing the city portion of the message. It gets the city name from theObject[] args = { labels.getString("RepCity") }; String result = MessageFormat.format(labels.getString("TimeLabel"), args); timeLabel.setText(result);labels
resource bundle. This array is used as an argument list toMessageFormat
'sformat
method.The second line of code formats the message with
MessageFormat.format
. Theformat
method requires two arguments: a pattern, and an array of arguments.AroundTheWorld
stores the pattern for this message in a resource bundle and retrieves it withlabels.getString("TimeLabel")
. If you look at the pattern in each of the resource bundles, you will notice the construct{0}
where the city name ought to be. This is a placeholder for the argument that will be filled in with a value from theargs
argument array. The number 0 is the argument number and is the index in the array where the value for this argument is stored.
MessageFormat.format( pattern , args)
formats the message and fills in the missing parts using the objects in theargs
array matching up the argument numbers and the array indices.And finally, the third line of code,
timeLabel.setText(result)
, sets the label in theLinguaPanel
with the formatted message.You will notice that
AroundTheWorld
did not use a factory method to create aMessageFormat
object like it did to create the number, and date and time formatters. Instead the program usedMessageFormat
's class methodformat
. This is because messages are all different and there is no notion of "the message that most programmers want". SoMessageFormat
cannot come up with a reasonble default. Thus to format messages, you either instantiate aMessageFormat
using its constructors and set it up, or you use the class methodMessageFormat.format
.The above example is fairly straightforward: The message contains one argument,
{0}
, which is filled in by the one object contained in a single-element array.MessageFormat
can handle complex messages that have multiple arguments and even recursive arguments. Also, the argument in the above example is a String that requires no special formatting itself.MessageFormat
can handle arguments of any type (numbers, dates) and use other formatters (NumberFormat
,DateFormat
) to format them.To get a better understanding of what
MessageFormat
can do, and how it does it, bring up the following demo applet provided by Taligent and try some of the suggestions in their guide.
![]() ![]() ![]() ![]() |
Locale-Sensitive Data |