[Reprint] http://www-128.ibm.com/developerworks/cn/java/j-mer08133/
java.text
The package allows formatting of text messages, dates, and numeric values in a way unrelated to a specific language. Many people cooperateMessageFormat
Class uses a resource package to localize messages for users. More people seem to useDateFormat
AndSimpleDateFormat
Class to operate the date string, used for both input and output. The most uncommon use seems to beNumberFormat
Class and Its Related subclassDecimalFormat
AndChoiceFormat
. In this month's discussion, we will look at the three classes that are not fully utilized andCurrency
Class to see how global j2se 1.4 has become.
Numeric formatting base class: numberformat
If you are from the United States, you will put a comma in the middle of a large value to represent thousands and millions (and so on, each three values use a comma ). For floating point numbers, place the decimal point between the integer part and the decimal part. For money, the currency symbol $ is placed before the amount. If you have never been outside the United States, you may not be concerned with the Japanese currency formatted using dollar (¥), the British currency formatted using pound (GBP, or the currencies of other European countries expressed in euros.
For currencies that we really care about, we can useNumberFormat
And related classes to format them. Use by developersNumberFormat
Class to read user input values and format the output to be displayed to the user.
AndDateFormat
Similarly,NumberFormat
Is an abstract class. You will never create an instance-instead, you always use its subclass. Although you can directly create a subclass through the subclass constructorNumberFormat
Class provides a seriesget XXXInstance()
Method to obtain the specific regional version of different types of numeric classes. There are five such methods:
getCurrencyInstance()
getInstance()
getIntegerInstance()
getNumberInstance()
getPercentInstance()
Which method is used depends on the type of value you want to display (or the type of input you want to accept ). Each method provides two versions-one version applies to the current region, and the other version accepts one locale as the parameter so that a different region may be specified.
In j2se 1.4,NumberFormat
The newly added content isgetIntegerInstance()、
getCurrency()
AndsetCurrency()
Method. Next let's look at the newgetIntegerInstance()
Method. The get/set currency method will be discussed later.
UseNumberFormat
The basic process is to obtain an instance and use it. Selecting the right instance does take a long time..Generally, you do not want to usegetInstance
OrgetNumberInstance()
Version,Because you do not know exactly what you will get. Opposite,You will usegetIntegerInstance()
This method,Because you want to display some content as integers without any small values.Listing 1 shows this.,We display the value 54321 as a format suitable for the United States and Germany.
Listing 1. Using numberformat
import java.text.*;import java.util.*;public class IntegerSample { public static void main(String args[]) { int amount = 54321; NumberFormat usFormat = NumberFormat.getIntegerInstance(Locale.US); System.out.println(usFormat.format(amount)); NumberFormat germanFormat = NumberFormat.getIntegerInstance(Locale.GERMANY); System.out.println(germanFormat.format(amount)); }}
|
Run this code to generate the output shown in Listing 2. Note the comma Separator in the first format (U.S.) and the dot Separator in the second format.
Listing 2. numberformat output
Learn how to iterate the characters in decimalformat
AlthoughNumberFormat
Is an abstract class, and you willgetIntegerInstance()
Such a variety of methods to use its instance,DecimalFormat
Class provides a specific version of the class. You can explicitly specify the character mode to determine how to display positive, negative, decimal, and exponent. If you do not like the predefined format used in different regions, you can create your own format. (Internally, maybeNumberFormat
Is usedDecimalFormat
.) BasicDecimalFormat
The function has not changed in version 1.4 of j2se platform. The change lies in the additionformatToCharacterIterator()、
getCurrency()
AndsetCurrency()
Method.
We will view the newformatToCharacterIterator
Methods and their associatedNumberFormat.Field
Class. J2se 1.4 introducedCharacterIterator
It allows two-way traversal of text. ForformatToCharacterIterator
, You will obtain its Sub-interfaceAttributedCharacterIterator
This sub-interface allows you to find information about the text. ForDecimalFormat
Status,Those attributes are fromNumberFormat.Field
Key.UseAttributedCharacterIterator
You can construct your own string output based on the generated results..Listing 3 uses a percentage instance to provide a simple demonstration:
Listing 3. Using formattocharacteriterator ()
import java.text.*;import java.util.*;public class DecimalSample { public static void main(String args[]) { double amount = 50.25; NumberFormat usFormat = NumberFormat.getPercentInstance(Locale.US); if (usFormat instanceof DecimalFormat) { DecimalFormat decFormat = (DecimalFormat)usFormat; AttributedCharacterIterator iter = decFormat.formatToCharacterIterator(new Double(amount)); for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) { // Get map for current character Map map = iter.getAttributes(); // Display its attributes System.out.println("Char: " + c + " / " + map); } } }}
|
Listing 4 shows the program output (displayed after a short message to make it easier to read ). Basically,formatToCharacterIterator()
Method work and callformat()
In addition to formatting the output string, the former also uses attributes to mark each character in the output (for example, is the character at position X an integer ?). 50.25 is displayed as a percentage, and the output in the United States is "5,025% ". Check the output,Each character except "%" is an integer, including a colon.Apart from numeric values,A comma is also marked as a group separator, and a percent is marked as a percent. The attribute of each number isjava.util.Map
And each attribute is displayedkey=value
(Key = value) format. If multiple attributes exist, the attributes in the attribute list are separated by commas.
Listing 4. formattocharacteriterator () Output
Char: 5 / {java.text.NumberFormat$Field(integer)= java.text.NumberFormat$Field(integer)}Char: , / {java.text.NumberFormat$Field(grouping separator)= java.text.NumberFormat$Field(grouping separator), java.text.NumberFormat$Field(integer)= java.text.NumberFormat$Field(integer)}Char: 0 / {java.text.NumberFormat$Field(integer)= java.text.NumberFormat$Field(integer)}Char: 2 / {java.text.NumberFormat$Field(integer)= java.text.NumberFormat$Field(integer)}Char: 5 / {java.text.NumberFormat$Field(integer)= java.text.NumberFormat$Field(integer)}Char: % / {java.text.NumberFormat$Field(percent)= java.text.NumberFormat$Field(percent)}
|
Determine the message based on the value range and choiceformat
ChoiceFormat
YesNumberFormat
Another concrete subclass. Its definition and behavior have not changed in j2se 1.4.ChoiceFormat
It does not really help you format a value, but it does allow you to customize the text associated with a value. In the simplest case, we can imagine an error message. If there is a single cause of failure, you want to use the word "is ". If there are two or more reasons, you want to use the word "are ". As shown in listing 5,ChoiceFormat
You can map a series of values to different text strings.
ChoiceFormat
NormallyMessageFormat
Class to generate messages that are not associated with the language. It is not explained how to useResourceBundle
(It usually correspondsChoiceFormat
To obtain the strings. Information on how to use a resource package,See references. In particular, the "Java internationalization basics" tutorial provides an in-depth discussion on this..
Listing 5. Using choiceformat
import java.text.*;import java.util.*;public class ChoiceSample { public static void main(String args[]) { double limits[] = {0, 1, 2}; String messages[] = { "is no content", "is one item", "are many items"}; ChoiceFormat formats = new ChoiceFormat(limits, messages); MessageFormat message = new MessageFormat("There {0}."); message.setFormats(new Format[]{formats}); for (int i=0; i<5; i++) { Object formatArgs[] = {new Integer(i)}; System.out.println(i + ": " + message.format(formatArgs)); } }}
|
Execute this program to generate the output shown in Listing 6:
Listing 6. choiceformat output
0: There is no content.1: There is one item.2: There are many items.3: There are many items.4: There are many items.
|
Use currency for currency Calculation
As mentioned abovegetCurrency()
AndsetCurrency()
Method returns a newjava.util.Currency
Class. This class allows access to different countriesISO 4217
Currency code. Although sincegetCurrencyInstance()
You can workNumberFormat
You can use it together. However, apart from displaying their numbers, you can never get or display currency symbols for a region. WithCurrency
Class, now it is easy to do this.
As mentioned above,The currency code comes from ISO 4217. Pass inLocale
Or the actual letter code of the currency,Currency.getInstance()
Returns a validCurrency
Object.NumberFormat
OfgetCurrency()
The method will do the same after creating a currency instance for a specific region. Listing 7 shows how to get a currency instance and how to format the value to be displayed as a currency. Remember that these conversions are only used for display. If you need to convert the amount between currencies, you should convert the amount before determining how to display the value.
Listing 7. Using getcurrencyinstance () and currency
import java.text.*;import java.util.*;import java.awt.*;import javax.swing.*;public class CurrencySample { public static void main(String args[]) { StringBuffer buffer = new StringBuffer(100); Currency dollars = Currency.getInstance("USD"); Currency pounds = Currency.getInstance(Locale.UK); buffer.append("Dollars: "); buffer.append(dollars.getSymbol()); buffer.append("/n"); buffer.append("Pound Sterling: "); buffer.append(pounds.getSymbol()); buffer.append("/n-----/n"); double amount = 5000.25; NumberFormat usFormat = NumberFormat.getCurrencyInstance(Locale.US); buffer.append("Symbol: "); buffer.append(usFormat.getCurrency().getSymbol()); buffer.append("/n"); buffer.append(usFormat.format(amount)); buffer.append("/n"); NumberFormat germanFormat = NumberFormat.getCurrencyInstance(Locale.GERMANY); buffer.append("Symbol: "); buffer.append(germanFormat.getCurrency().getSymbol()); buffer.append("/n"); buffer.append(germanFormat.format(amount)); JFrame frame = new JFrame("Currency"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JTextArea ta = new JTextArea(buffer.toString()); JScrollPane pane = new JScrollPane(ta); frame.getContentPane().add(pane, BorderLayout.CENTER); frame.setSize(200, 200); frame.show(); }}
|
Unfortunately, the currency symbol returned for the euro or pound is not an actual symbol, but a three-digit currency code (from ISO 4217 ). HowevergetCurrencyInstance()
The actual symbols are displayed, as shown in 1.
Figure 1. view the actual currency symbol
Conclusion
For software globalization, more than custom text messages are required. Although the text message is transferred to the resource package at least half of the work, do not forget to process the value and currency display closely related to the region. Not everyone uses colons and dots to display numbers like they do in the United States. Everyone must process their currency details. Although we do not have to rely on vintage COBOL graphical strings such as $. 99, by using region-specificNumberFormat
Instance, you can make your programs more international.