Output from the program:
Requested Locale: en_US
Arguments:[0.5] Result: There are no bananas.
Arguments:[1.5] Result: There is only one banana.
Arguments:[2.5, 2] Result: There are 2 bananas.
Requested Locale: es_ES
Arguments:[0.5] Result: Ahí no hay plátanos.
Arguments:[1.5] Result: Ahí es solo un plátano.
Arguments:[2.5, 2] Result: Ahí son 2 plátanos.
Example 18.9 illustrates using a choice format for handling plurals. Example 18.10 illustrates an alternative approach where the choice format is created programmatically using the ChoiceFormat class.
The class ChoiceFormat provides the following constructors for creating a choice format either programmatically or using a pattern.
ChoiceFormat(double[] limits, String[] formats)
Creates a ChoiceFormat with the limits specified in ascending order and the corresponding formats.
ChoiceFormat(String newPattern)
Creates a ChoiceFormat with limits and corresponding formats based on the specified pattern string.
The ChoiceFormat class is locale-agnostic—that is, providing no locale-specific operations. However, the class MessageFormat implements locale-specific operations, and allows formats to be set for individual format elements in its pattern. By setting a ChoiceFormat as a format for a choice format element in a locale-sensitive MessageFormat, it is possible to achieve locale-specific formatting behavior in a ChoiceFormat. This approach is illustrated in Example 18.10. The numbers below correspond to the numbers on the lines in the source code for Example 18.10.
(1) The locale-specific resource bundle with resources for the pattern and for constructing the choice format is fetched. See the listing of the resource bundle file in Example 18.10.
(2) A locale-specific MessageFormat is created based on the pattern (“There {0}.”) which is read from the resource bundle.
(3) To create a ChoiceFormat programmatically requires two equal-length arrays that contain the limits and the corresponding subformats, respectively. The double array limits is created with the limit values 0, 1, and 2. A String array messageFormats is created by reading the values of the keys none, singular, and plural from the resource bundle. These are the subformats corresponding to the limits that we saw in the choice format in Example 18.9.
(4) Given the arrays for the limits and the subformats, the ChoiceFormat constructor creates the choice format.
(5) and (6) One way to set customized formats for individual format elements in a MessageFormat is by first creating an array of Format (superclass of format classes in java.text package). The order of the formats in this array must be the same as either the order of format elements in the pattern string or the order of elements in the argument array passed to the format methods. There is only one format element in the pattern (“There {0}.”). The array of Format thus has only one element which is the choice format for this format element, and therefore, both orders are valid in this case. We can use either the setFormats() or the setFormatsByArgumentIndex() method, as shown at (6a) and (6b), respectively. Either method will associate the choice format with the format element having the argument index 0 in the pattern.
However, the format for the format element at the argument index 0 in the pattern can easily be set by calling the setFormat() method, as shown at (6c).
(7) through (9) The behavior of the program is exactly the same as for Example 18.9. Experimenting with other limits and arguments is recommended.
Example 18.10 Using the ChoiceFormat Class
# File: ChoiceBundle.properties
…
pattern = There {0}.
none = are no bananas
singular = is only one banana
plural = are {1,number,integer} bananas
import java.text.*;
import java.util.*;
public class ChoiceFormatUsage {
static void displayMessages(Locale requestedLocale) {
System.out.println(“Requested locale: ” + requestedLocale);
// Fetch the resource bundle: (1)
ResourceBundle bundle =
ResourceBundle.getBundle(“resources.ChoiceBundle”, requestedLocale);
// Create formatter for specified pattern and locale: (2)
MessageFormat mf = new MessageFormat(
bundle.getString(“pattern”), // pattern = There {0}.
requestedLocale
);
// Create the limits and the formats arrays: (3)
double[] limits = {0,1,2}; // (3a)
String [] grammarFormats = { // (3b)
bundle.getString(“none”), // none = are no bananas
bundle.getString(“singular”), // singular = is only one banana
bundle.getString(“plural”) // plural = are {1,number,integer} bananas
};
// Create the choice format: (4)
ChoiceFormat choiceForm = new ChoiceFormat(limits, grammarFormats);
// Create the formats: (5)
Format[] formats = {choiceForm};
// Set the formats in the formatter: (6)
mf.setFormats(formats); // (6a)
// messageForm.setFormatsByArgumentIndex(formats); // (6b)
// mf.setFormat(0, choiceForm); // (6c)
// Create the arguments arrays: (7)
Object[][] messageArguments = { {0.5}, {1.5}, {2.5, 2} };
// Test the formatter with arguments: (8)
for (int choiceNumber = 0;
choiceNumber < messageArguments.length; choiceNumber++) {
String result = mf.format(messageArguments[choiceNumber]); // (9)
System.out.printf(“Arguments:%-10sResult: %s%n”,
Arrays.toString(messageArguments[choiceNumber]),result); }
}
public static void main(String[] args) {
displayMessages(new Locale(“en”, “US”));
System.out.println();
displayMessages(new Locale(“es”, “ES”));
}
}
Output from the program:
Arguments:[0.5] Result: There are no bananas.
Arguments:[1.5] Result: There is only one banana.
Arguments:[2.5, 2] Result: There are 2 bananas.
Requested locale: es_ES
Arguments:[0.5] Result: Ahí no hay plátanos.
Arguments:[1.5] Result: Ahí es solo un plátano.
Arguments:[2.5, 2] Result: Ahí son 2 plátanos.
Leave a Reply