|
|
|
|
We can change the way each object is displayed in the formatted string, by:
Using the
|
package inputOutput;
import java.text.MessageFormat;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.GregorianCalendar;
public class FormatText
{
public static void main(String[] args)
{
String pattern =
"On {2}, a {0} destroyed {1} houses and caused {3} of damage.";
MessageFormat msgFormat = new MessageFormat(pattern);
msgFormat.setFormat(0, DateFormat.getDateInstance(DateFormat.LONG));
msgFormat.setFormat(3, NumberFormat.getCurrencyInstance());
Object[] msgArgs =
{
"hurricane",
new Integer(99),
new GregorianCalendar(1999, 0, 1).getTime(),
new Double(10E7)
};
System.out.println(msgFormat.format(msgArgs));
}
} |
which produces:
On January 1, 1999, a hurricane destroyed 99 houses and caused $100,000,000.00 of damage.
setFormats methodWe could have accomplished the same thing as follows:
package inputOutput;
import java.text.MessageFormat;
import java.text.DateFormat;
import java.text.Format;
import java.text.NumberFormat;
import java.util.GregorianCalendar;
public class FormatText
{
public static void main(String[] args)
{
String pattern =
"On {2}, a {0} destroyed {1} houses and caused {3} of damage.";
MessageFormat msgFormat = new MessageFormat(pattern);
Format argFormats[] =
{
DateFormat.getDateInstance(DateFormat.LONG),
null,
null,
NumberFormat.getCurrencyInstance()
};
msgFormat.setFormats(argFormats);
Object[] msgArgs =
{
"hurricane",
new Integer(99),
new GregorianCalendar(1999, 0, 1).getTime(),
new Double(10E7)
};
System.out.println(msgFormat.format(msgArgs));
}
} |
You can repeat the same argument, but with a different format:
package inputOutput;
import java.text.MessageFormat;
import java.text.DateFormat;
import java.text.Format;
import java.util.GregorianCalendar;
public class FormatText
{
public static void main(String[] args)
{
String pattern =
"On {2}, a {0} touched down at {2} and destroyed {1} houses.";
MessageFormat msgFormat = new MessageFormat(pattern);
Format argFormats[] =
{
DateFormat.getDateInstance(DateFormat.LONG),
null,
DateFormat.getTimeInstance(DateFormat.SHORT),
null
};
msgFormat.setFormats(argFormats);
Object[] msgArgs =
{
"tornado",
new Integer(99),
new GregorianCalendar(1999, 0, 1).getTime()
};
System.out.println(msgFormat.format(msgArgs));
}
} |
which outputs:
On January 1, 1999, a tornado touched down at 12:00 AM and destroyed 99 houses.
Note: The argument formats correspond to the position of the placeholder, while the message arguments correspond to the number of the placeholder.
Another way of controlling the format is to specify the formats in the placeholder itself:
package inputOutput;
import java.text.MessageFormat;
import java.util.GregorianCalendar;
public class FormatText
{
public static void main(String[] args)
{
String pattern =
"On {2,date,long}, a {0} touched down at {2,time,short}, " +
"destroyed {1} houses, and caused {3,number,currency} of damage.";
MessageFormat msgFormat = new MessageFormat(pattern);
Object[] msgArgs =
{
"tornado",
new Integer(99),
new GregorianCalendar(1999, 0, 1).getTime(),
new Double(10E7)
};
System.out.println(msgFormat.format(msgArgs));
}
} |
which produces:
On January 1, 1999, a tornado touched down at 12:00 AM, destroyed 99 houses, and caused $100,000,000.00 of damage.
Consider the following modification of the above program:
package inputOutput;
import java.text.MessageFormat;
import java.util.GregorianCalendar;
public class FormatText
{
public static void main(String[] args)
{
String pattern =
"On {2,date,long}, a {0} " +
"destroyed {1} houses, and caused {3,number,currency} of damage.";
MessageFormat msgFormat = new MessageFormat(pattern);
Object[] msgArgs =
{
"earthquake",
new Integer(1),
new GregorianCalendar(1999, 0, 1).getTime(),
new Double(10E7)
};
System.out.println(msgFormat.format(msgArgs));
}
} |
This outputs the string:
On January 1, 1999, a earthquake destroyed 1 houses, and caused $100,000,000.00 of damage.
which should, to be grammatically correct, read:
On January 1, 1999, an earthquake destroyed 1 house, and caused $100,000,000.00 of damage.
In other words, we have to deal with plurals correctly, as well as ensuring that parts of speech match properly (such as indefinite articles, etc.). This can be more important and more complex in other languages such as German or French, where articles must match the gender and context of a noun.
ChoiceFormat
was designed to let you solve this problem. You must specify:
Here's an example of how to solve the above problem:
package inputOutput;
import java.text.ChoiceFormat;
import java.text.MessageFormat;
import java.util.GregorianCalendar;
public class FormatText
{
public static void main(String[] args)
{
double[] limits = {1, 1, 2};
String[] formatStrings =
{"no houses", "one house",
"{1,number,integer} houses"};
ChoiceFormat choiceFormat =
new ChoiceFormat(limits, formatStrings);
String pattern =
"On {2,date,long}, {0} " +
"destroyed {1}, and caused {3,number,currency} of damage.";
MessageFormat msgFormat = new MessageFormat(pattern);
msgFormat.setFormat(2, choiceFormat);
Object[] msgArgs =
{
"an earthquake",
new Integer(1),
new GregorianCalendar(1999, 0, 1).getTime(),
new Double(10E7)
};
System.out.println(msgFormat.format(msgArgs));
}
} |
which outputs:
On January 1, 1999, an earthquake destroyed one house, and caused $100,000,000.00 of damage.
Or, we can embed the same choices into the placeholders themselves:
package inputOutput;
import java.text.MessageFormat;
import java.util.GregorianCalendar;
public class FormatText
{
public static void main(String[] args)
{
String pattern =
"On {2,date,long}, {0} destroyed " +
"{1,choice,0#no houses|1#one house|2#{1,number,integer} houses}, " +
"and caused {3,number,currency} of damage.";
MessageFormat msgFormat = new MessageFormat(pattern);
Object[] msgArgs =
{
"an earthquake",
new Integer(1),
new GregorianCalendar(1999, 0, 1).getTime(),
new Double(10E7)
};
System.out.println(msgFormat.format(msgArgs));
}
} |
This is actually far preferred, because it means that we can remove the message(s) from the program, and provide separate sets of messages for each language/locale, and have the separated messages contain all the necessary instructions to format the messages correctly in each language. That way, the program does not have special code for each language.
Believe me, this is very important when you are writing code that will have to be internationalized (globalization is here, already!)
| The page was last updated February 19, 2008 |