处理复合消息

原文: https://docs.oracle.com/javase/tutorial/i18n/format/messageFormat.html

复合邮件可能包含多种变量:日期,时间,字符串,数字,货币和百分比。要以与语言环境无关的方式格式化复合邮件,可以构造应用于MessageFormat对象的模式,并将此模式存储在ResourceBundle中。

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

1.识别消息中的变量

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

The following line of text: At 1:15 on April 13, 1998, we detected 7 spaceships on the planet Mars.  The variable data (1:15, April 13,1998, 7, and Mars) have been underlined.

请注意,我们已经为变量数据加下划线,并确定了哪种对象将代表这些数据。

2.隔离 ResourceBundle 中的消息模式

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

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

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

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

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

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

Arguments for template in MessageBundle_en_US.properties | 争论 | 描述 | | —- | —- | | {2,time,short} | Date对象的时间部分。 short样式指定DateFormat.SHORT格式样式。 | | {2,date,long} | Date对象的日期部分。相同的Date对象用于日期和时间变量。在Object参数数组中,保存Date对象的元素的索引是 2.(这将在下一步中介绍。) | | {1,number,integer} | 一个Number对象,进一步使用integer编号样式限定。 | | {0} | ResourceBundle中与planet键对应的String。 |

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

3.设置消息参数

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

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

4.创建格式化程序

接下来,创建一个MessageFormat对象。您设置Locale,因为该消息包含DateNumber对象,这些对象应以区域设置敏感的方式格式化。

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

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

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

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

6.运行演示程序

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

  1. currentLocale = en_US
  2. At 10:16 AM on July 31, 2009, we detected 7
  3. spaceships on the planet Mars.
  4. currentLocale = de_DE
  5. Um 10:16 am 31\. Juli 2009 haben wir 7 Raumschiffe
  6. auf dem Planeten Mars entdeckt.