分享
 
 
 

Formatting messages with variable content

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

Internationalization is the process of designing an application to work with multiple languages and in regions around the world. This not only involves translating text labels to other languages. It also also means displaying information such as dates and times in a format appropriate for that particular region of the globe.

The first step involved in internationalizing text labels and messages is to move everything into resource bundles. For each quoted string you want the user to see, you create an entry in a resource bundle. Then, you change the code to dynamically look up the text label or message based on the locale of the user. When you do this correctly, a user in the United States might see Help as the label for a help menu, while a Spanish user would see Ayuda.

This technique works perfectly well for straight text-to-text translations, where you are always displaying a "whole" message. However this technique doesn't work for compound messages, where you need to combine several pieces of a message into one longer message. For instance, consider the following message:

Hello, John. Good luck.

You might think that you could simply use string concatenation, and build the compound message by appending multiple strings together:

System.out.println(

"Hello, " +

name +

". Good luck.")

You might also assume that you could localize the compound message by moving the Hello and Good luck strings into resource bundles. This might work, but what happens when you get to a language where the form of the greeting becomes something like:

Hello and good luck, John.

You could break up the resource bundle strings into a prefix part before the name, and a suffix part after the name. But this complicates things for translators because they must know what pieces go together. A better approach is to have one text string, with a variable holder in the middle for the name.

For English, that string might be:

Hello, {0}. Good luck.

Seeing that whole string, a translator for Spanish might realize it is better to put hello and good luck together, as follows:

Hola y buena suerte, {0}.

When it's time to actually display the message, the MessageFormat class of the java.text package can be used to replace the variables. MessageFormat takes a set of objects, formats them, and inserts the formatted strings into a pattern. The pattern could be something like "Hello, {0}. Good luck."

To use MessageFormat, you start by creating a formatter:

String pattern = ...; // from bundle

Locale aLocale = ...; // the Locale

MessageFormat formatter = new MessageFormat(pattern);

formatter.setLocale(aLocale);

For each pattern, you could create different MessageFormat objects. However you can also reuse the MessageFormat object with another pattern by calling the applyPattern method with the new pattern template. Remember to do this after changing locales:

formatter.setLocale(aNewLocale);

formatter.applyPattern(aPatternForNewLocale);

After you have the formatter, you need to generate the output message. To do this, you pass in an array of arguments, where each {#} in the pattern is replaced, based on its index in the array. For instance, a one element array is needed for the pattern "Hello, {0}. Good luck." The one element in the array contains the text that will be inserted at position 0 in the string. Here's an example -- it's a one element array that contains the string "John" for insertion into the previous pattern:

Object messageArgs[] = {"John"};

To generate the output, you call the format method of MessageFormat, specifying the message arguments:

System.out.println(formatter.format(messageArgs));

The following program, HelloGoodLuck, demonstrates the use of MessageFormat. To keep things simple, the program doesn't use resource bundles:

import java.text.*;

import java.util.*;

public class HelloGoodLuck {

public static void main(String args[]) {

String pattern = "Hello, {0}. Good luck.";

Locale aLocale = Locale.US;

MessageFormat formatter = new MessageFormat(

pattern, aLocale);

Object messageArgs[] = {"John"};

System.out.println(

formatter.format(messageArgs));

// Pass in command line args

if (args.length != 0) {

System.out.println(formatter.format(args));

}

}

}

The HelloGoodLuck program produces a second message if you pass in a name on the command line. If you run the program with the following command:

java HelloGoodLuck Spot

You should see the output:

Hello, John. Good luck.

Hello, Spot. Good luck.

Using MessageFormat is not limited to text substitution. You can also use it to format numbers and dates, that is, without having to use the NumberFormat and DateFormat classes. The javadoc for the MessageFormat class describes all the support available.

After the argument index part of {#}, you can specify a format type and a style (separated by commas). For instance, in the case of a date, you can specify a short, medium, long, or full to map to the DateFormat constants. If the argument type is a Date, and the MessageFormat maps that argument to "{1,date,long}", you would see the long format for a date displayed (in a format appropriate for the locale). You can also display dates with a "time" type, using the same short, medium, long, full options. For a number, the available styles include integer, currency, and percent. If you don't like the built-in styles, and know the pattern strings of SimpleDateFormat and DecimalFormat, you can also specify those directly.

To demonstrate, the following MessageFormat pattern uses time, date, and number:

At the tone, the time is now {0, time, short}

on {0, date, long}.

You now owe us {1, number, currency}.

If you then provided a Date and Number as the input argument, it would generate output for US-English and German locales.

And here is the program that produces that output. To keep the demonstration simple, resource bundles were not used. However, the strings in the pattern and germanPattern variables in the program should be located in resource bundles.

import java.text.*;

import java.util.*;

import java.io.*;

import java.awt.*;

import javax.swing.*;

public class ExtendedFormat {

public static void main(String args[]) {

String pattern =

"At the tone, the time is now {0, time, short}" +

" on {0, date, long}." +

" You now owe us {1, number, currency}.";

String germanPattern =

"Beim Zeitton ist es {0, time, short} Uhr" +

" am {0, date, long}." +

" Sie schulden uns jetzt {1, number, currency}.";

StringWriter sw = new StringWriter(100);

PrintWriter out = new PrintWriter(sw, true);

MessageFormat formatter =

new MessageFormat(pattern, Locale.US);

Object messageArgs[] =

{new Date(), new Double(9000.12)};

out.println(formatter.format(messageArgs));

formatter.setLocale(Locale.GERMAN);

// Need to reset pattern after changing locales

formatter.applyPattern(germanPattern);

out.println(formatter.format(messageArgs));

out.close();

// Put output in window

JFrame frame = new JFrame("Extended Format");

frame.setDefaultCloseOperation(

JFrame.EXIT_ON_CLOSE);

JTextArea ta = new JTextArea(sw.toString());

JScrollPane pane = new JScrollPane(ta);

frame.getContentPane().add(

pane, BorderLayout.CENTER);

frame.setSize(500, 100);

frame.show();

}

}

There is much more to properly internationalizing your applications than using MessageFormat. For more information on the use of resource bundles (where all these string patterns should come from), see the May 21, 1998 Tech Tip, "Resource Bundles". Also, for more information on formatting date and time strings, see the June 24, 2003 Tech Tip, "Internationalizing Dates, Times, Months, and Days of the Week".

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有