📄 messageformat.java
字号:
* objs = mf.parse(result, new ParsePosition(0)); * // objs now equals {new Double(3.1)} * </pre> * <p> * Likewise, parsing with a MessageFormat object using patterns containing * multiple occurances of the same argument would return the last match. For * example, * <pre> * MessageFormat mf = new MessageFormat("{0}, {0}, {0}"); * String forParsing = "x, y, z"; * Object[] objs = mf.parse(forParsing, new ParsePosition(0)); * // result now equals {new String("z")} * </pre> * * <h4><a name="synchronization">Synchronization</a></h4> * * <p> * Message formats are not synchronized. * It is recommended to create separate format instances for each thread. * If multiple threads access a format concurrently, it must be synchronized * externally. * * @see java.util.Locale * @see Format * @see NumberFormat * @see DecimalFormat * @see ChoiceFormat * @version 1.51, 01/23/03 * @author Mark Davis */public class MessageFormat extends Format { private static final long serialVersionUID = 6479157306784022952L; /** * Constructs a MessageFormat for the default locale and the * specified pattern. * The constructor first sets the locale, then parses the pattern and * creates a list of subformats for the format elements contained in it. * Patterns and their interpretation are specified in the * <a href="#patterns">class description</a>. * * @param pattern the pattern for this message format * @exception IllegalArgumentException if the pattern is invalid */ public MessageFormat(String pattern) { this.locale = Locale.getDefault(); applyPattern(pattern); } /** * Constructs a MessageFormat for the specified locale and * pattern. * The constructor first sets the locale, then parses the pattern and * creates a list of subformats for the format elements contained in it. * Patterns and their interpretation are specified in the * <a href="#patterns">class description</a>. * * @param pattern the pattern for this message format * @param locale the locale for this message format * @exception IllegalArgumentException if the pattern is invalid * @since 1.4 */ public MessageFormat(String pattern, Locale locale) { this.locale = locale; applyPattern(pattern); } /** * Sets the locale to be used when creating or comparing subformats. * This affects subsequent calls to the {@link #applyPattern applyPattern} * and {@link #toPattern toPattern} methods as well as to the * <code>format</code> and * {@link #formatToCharacterIterator formatToCharacterIterator} methods. * * @param locale the locale to be used when creating or comparing subformats */ public void setLocale(Locale locale) { this.locale = locale; } /** * Gets the locale that's used when creating or comparing subformats. * * @return the locale used when creating or comparing subformats */ public Locale getLocale() { return locale; } /** * Sets the pattern used by this message format. * The method parses the pattern and creates a list of subformats * for the format elements contained in it. * Patterns and their interpretation are specified in the * <a href="#patterns">class description</a>. * * @param pattern the pattern for this message format * @exception IllegalArgumentException if the pattern is invalid */ public void applyPattern(String pattern) { StringBuffer[] segments = new StringBuffer[4]; for (int i = 0; i < segments.length; ++i) { segments[i] = new StringBuffer(); } int part = 0; int formatNumber = 0; boolean inQuote = false; int braceStack = 0; maxOffset = -1; for (int i = 0; i < pattern.length(); ++i) { char ch = pattern.charAt(i); if (part == 0) { if (ch == '\'') { if (i + 1 < pattern.length() && pattern.charAt(i+1) == '\'') { segments[part].append(ch); // handle doubles ++i; } else { inQuote = !inQuote; } } else if (ch == '{' && !inQuote) { part = 1; } else { segments[part].append(ch); } } else if (inQuote) { // just copy quotes in parts segments[part].append(ch); if (ch == '\'') { inQuote = false; } } else { switch (ch) { case ',': if (part < 3) part += 1; else segments[part].append(ch); break; case '{': ++braceStack; segments[part].append(ch); break; case '}': if (braceStack == 0) { part = 0; makeFormat(i, formatNumber, segments); formatNumber++; } else { --braceStack; segments[part].append(ch); } break; case '\'': inQuote = true; // fall through, so we keep quotes in other parts default: segments[part].append(ch); break; } } } if (braceStack == 0 && part != 0) { maxOffset = -1; throw new IllegalArgumentException("Unmatched braces in the pattern."); } this.pattern = segments[0].toString(); } /** * Returns a pattern representing the current state of the message format. * The string is constructed from internal information and therefore * does not necessarily equal the previously applied pattern. * * @return a pattern representing the current state of the message format */ public String toPattern() { // later, make this more extensible int lastOffset = 0; StringBuffer result = new StringBuffer(); for (int i = 0; i <= maxOffset; ++i) { copyAndFixQuotes(pattern, lastOffset, offsets[i],result); lastOffset = offsets[i]; result.append('{'); result.append(argumentNumbers[i]); if (formats[i] == null) { // do nothing, string format } else if (formats[i] instanceof DecimalFormat) { if (formats[i].equals(NumberFormat.getInstance(locale))) { result.append(",number"); } else if (formats[i].equals(NumberFormat.getCurrencyInstance(locale))) { result.append(",number,currency"); } else if (formats[i].equals(NumberFormat.getPercentInstance(locale))) { result.append(",number,percent"); } else if (formats[i].equals(NumberFormat.getIntegerInstance(locale))) { result.append(",number,integer"); } else { result.append(",number," + ((DecimalFormat)formats[i]).toPattern()); } } else if (formats[i] instanceof SimpleDateFormat) { if (formats[i].equals(DateFormat.getDateInstance( DateFormat.DEFAULT,locale))) { result.append(",date"); } else if (formats[i].equals(DateFormat.getDateInstance( DateFormat.SHORT,locale))) { result.append(",date,short"); } else if (formats[i].equals(DateFormat.getDateInstance( DateFormat.DEFAULT,locale))) { result.append(",date,medium"); } else if (formats[i].equals(DateFormat.getDateInstance( DateFormat.LONG,locale))) { result.append(",date,long"); } else if (formats[i].equals(DateFormat.getDateInstance( DateFormat.FULL,locale))) { result.append(",date,full"); } else if (formats[i].equals(DateFormat.getTimeInstance( DateFormat.DEFAULT,locale))) { result.append(",time"); } else if (formats[i].equals(DateFormat.getTimeInstance( DateFormat.SHORT,locale))) { result.append(",time,short"); } else if (formats[i].equals(DateFormat.getTimeInstance( DateFormat.DEFAULT,locale))) { result.append(",time,medium"); } else if (formats[i].equals(DateFormat.getTimeInstance( DateFormat.LONG,locale))) { result.append(",time,long"); } else if (formats[i].equals(DateFormat.getTimeInstance( DateFormat.FULL,locale))) { result.append(",time,full"); } else { result.append(",date," + ((SimpleDateFormat)formats[i]).toPattern()); } } else if (formats[i] instanceof ChoiceFormat) { result.append(",choice," + ((ChoiceFormat)formats[i]).toPattern()); } else { //result.append(", unknown"); } result.append('}'); } copyAndFixQuotes(pattern, lastOffset, pattern.length(), result); return result.toString(); } /** * Sets the formats to use for the values passed into * <code>format</code> methods or returned from <code>parse</code> * methods. The indices of elements in <code>newFormats</code> * correspond to the argument indices used in the previously set * pattern string. * The order of formats in <code>newFormats</code> thus corresponds to * the order of elements in the <code>arguments</code> array passed * to the <code>format</code> methods or the result array returned * by the <code>parse</code> methods. * <p> * If an argument index is used for more than one format element * in the pattern string, then the corresponding new format is used * for all such format elements. If an argument index is not used * for any format element in the pattern string, then the * corresponding new format is ignored. If fewer formats are provided * than needed, then only the formats for argument indices less * than <code>newFormats.length</code> are replaced. * * @param newFormats the new formats to use * @exception NullPointerException if <code>newFormats</code> is null * @since 1.4 */ public void setFormatsByArgumentIndex(Format[] newFormats) { for (int i = 0; i <= maxOffset; i++) { int j = argumentNumbers[i]; if (j < newFormats.length) { formats[i] = newFormats[j]; } } } /** * Sets the formats to use for the format elements in the * previously set pattern string. * The order of formats in <code>newFormats</code> corresponds to * the order of format elements in the pattern string. * <p> * If more formats are provided than needed by the pattern string, * the remaining ones are ignored. If fewer formats are provided * than needed, then only the first <code>newFormats.length</code> * formats are replaced. * <p> * Since the order of format elements in a pattern string often * changes during localization, it is generally better to use the * {@link #setFormatsByArgumentIndex setFormatsByArgumentIndex} * method, which assumes an order of formats corresponding to the * order of elements in the <code>arguments</code> array passed to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -