处理复合消息

复合消息可能包含多种变量:日期,时间,字符串,数字,货币和百分比。要以与语言环境无关的方式设置复合消息的格式,请构造一个应用于MessageFormat对象的 Pattern,然后将此 Pattern 存储在ResourceBundle中。

通过逐步执行示例程序,本节演示了如何使复合消息国际化。该示例程序使用了MessageFormat类。该程序的完整源代码在名为MessageFormatDemo.java的文件中。德语语言环境属性位于名为MessageBundle_de_DE.properties的文件中。

1.识别消息中的变量

假设您要国际化以下消息:

请注意,我们已在变量数据下划线,并确定了哪种对象将代表此数据。

2.隔离 ResourceBundle 中的消息 Pattern

将消息存储在名为MessageBundleResourceBundle中,如下所示:

ResourceBundle messages =
   ResourceBundle.getBundle("MessageBundle", currentLocale);

ResourceBundle由每个Locale的属性文件支持。由于ResourceBundle称为MessageBundle,因此美国英语的属性文件名为MessageBundle_en_US.properties。该文件的内容如下:

template = At {2,time,short} on {2,date,long}, \
    we detected {1,number,integer} spaceships on \
    the planet {0}.
planet = Mars

属性文件的第一行包含消息 Pattern。如果将此 Pattern 与步骤 1 中显示的消息文本进行比较,您将看到括号中的参数将替换消息文本中的每个变量。每个参数都以一个称为参数编号的数字开头,该数字与保存参数值的Object数组中元素的索引匹配。请注意,在 Pattern 中,参数编号没有任何特定的 Sequences。您可以将参数放在 Pattern 中的任何位置。唯一的要求是参数编号在参数值数组中具有匹配的元素。

下一步讨论参数值数组,但首先让我们看一下 Pattern 中的每个参数。下表提供了有关参数的一些详细信息:

Argument Description
{2,time,short} Date对象的时间部分。 short样式指定DateFormat.SHORT格式样式。
{2,date,long} Date对象的日期部分。相同的Date对象用于日期和时间变量。在Object参数数组中,保存Date对象的元素的索引为 2.(在下一步中进行说明.)
{1,number,integer} Number对象,进一步具有integer数字样式。
{0} ResourceBundle中的Stringplanet键相对应。

有关参数语法的完整说明,请参见MessageFormat类的 API 文档。

3.设置消息参数

以下代码行为 Pattern 中的每个参数分配值。 messageArguments数组中元素的索引与 Pattern 中的参数编号匹配。例如,索引 1 处的Integer元素对应于 Pattern 中的{1,number,integer}参数。因为必须翻译它,所以将使用getString方法从ResourceBundle中获取元素 0 的String对象。这是定义消息参数数组的代码:

Object[] messageArguments = {
    messages.getString("planet"),
    new Integer(7),
    new Date()
};

4.创建格式化程序

接下来,创建一个MessageFormat对象。您设置Locale是因为消息包含DateNumber对象,应以对语言环境敏感的方式对其进行格式化。

MessageFormat formatter = new MessageFormat("");
formatter.setLocale(currentLocale);

5.使用 Pattern 和参数格式化消息

此步骤显示 Pattern,消息参数和格式化程序如何一起工作。首先,使用getString方法从ResourceBundle获取 PatternString。Pattern 的关键是template。使用applyPattern方法将 PatternString传递给格式化程序。然后,通过调用format方法,使用消息参数数组来格式化消息。 format方法返回的String准备显示。所有这些仅需两行代码即可完成:

formatter.applyPattern(messages.getString("template"));
String output = formatter.format(messageArguments);

6.运行演示程序

该演示程序将打印英语和德语语言环境的翻译后的消息,并正确格式化日期和时间变量。请注意,英语和德语动词(“ detected”和“ entdeckt”)相对于变量位于不同的位置:

currentLocale = en_US
At 10:16 AM on July 31, 2009, we detected 7
spaceships on the planet Mars.
currentLocale = de_DE
Um 10:16 am 31. Juli 2009 haben wir 7 Raumschiffe
auf dem Planeten Mars entdeckt.
首页