42 import java.io.IOException; |
42 import java.io.IOException; |
43 import java.io.ObjectInputStream; |
43 import java.io.ObjectInputStream; |
44 import java.util.Arrays; |
44 import java.util.Arrays; |
45 |
45 |
46 /** |
46 /** |
47 * A <code>ChoiceFormat</code> allows you to attach a format to a range of numbers. |
47 * A {@code ChoiceFormat} allows you to attach a format to a range of numbers. |
48 * It is generally used in a <code>MessageFormat</code> for handling plurals. |
48 * It is generally used in a {@code MessageFormat} for handling plurals. |
49 * The choice is specified with an ascending list of doubles, where each item |
49 * The choice is specified with an ascending list of doubles, where each item |
50 * specifies a half-open interval up to the next item: |
50 * specifies a half-open interval up to the next item: |
51 * <blockquote> |
51 * <blockquote> |
52 * <pre> |
52 * <pre> |
53 * X matches j if and only if limit[j] ≤ X < limit[j+1] |
53 * X matches j if and only if limit[j] ≤ X < limit[j+1] |
58 * in ascending order, the results of formatting will be incorrect. ChoiceFormat |
58 * in ascending order, the results of formatting will be incorrect. ChoiceFormat |
59 * also accepts <code>\u221E</code> as equivalent to infinity(INF). |
59 * also accepts <code>\u221E</code> as equivalent to infinity(INF). |
60 * |
60 * |
61 * <p> |
61 * <p> |
62 * <strong>Note:</strong> |
62 * <strong>Note:</strong> |
63 * <code>ChoiceFormat</code> differs from the other <code>Format</code> |
63 * {@code ChoiceFormat} differs from the other {@code Format} |
64 * classes in that you create a <code>ChoiceFormat</code> object with a |
64 * classes in that you create a {@code ChoiceFormat} object with a |
65 * constructor (not with a <code>getInstance</code> style factory |
65 * constructor (not with a {@code getInstance} style factory |
66 * method). The factory methods aren't necessary because <code>ChoiceFormat</code> |
66 * method). The factory methods aren't necessary because {@code ChoiceFormat} |
67 * doesn't require any complex setup for a given locale. In fact, |
67 * doesn't require any complex setup for a given locale. In fact, |
68 * <code>ChoiceFormat</code> doesn't implement any locale specific behavior. |
68 * {@code ChoiceFormat} doesn't implement any locale specific behavior. |
69 * |
69 * |
70 * <p> |
70 * <p> |
71 * When creating a <code>ChoiceFormat</code>, you must specify an array of formats |
71 * When creating a {@code ChoiceFormat}, you must specify an array of formats |
72 * and an array of limits. The length of these arrays must be the same. |
72 * and an array of limits. The length of these arrays must be the same. |
73 * For example, |
73 * For example, |
74 * <ul> |
74 * <ul> |
75 * <li> |
75 * <li> |
76 * <em>limits</em> = {1,2,3,4,5,6,7}<br> |
76 * <em>limits</em> = {1,2,3,4,5,6,7}<br> |
77 * <em>formats</em> = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat"} |
77 * <em>formats</em> = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat"} |
78 * <li> |
78 * <li> |
79 * <em>limits</em> = {0, 1, ChoiceFormat.nextDouble(1)}<br> |
79 * <em>limits</em> = {0, 1, ChoiceFormat.nextDouble(1)}<br> |
80 * <em>formats</em> = {"no files", "one file", "many files"}<br> |
80 * <em>formats</em> = {"no files", "one file", "many files"}<br> |
81 * (<code>nextDouble</code> can be used to get the next higher double, to |
81 * ({@code nextDouble} can be used to get the next higher double, to |
82 * make the half-open interval.) |
82 * make the half-open interval.) |
83 * </ul> |
83 * </ul> |
84 * |
84 * |
85 * <p> |
85 * <p> |
86 * Here is a simple example that shows formatting and parsing: |
86 * Here is a simple example that shows formatting and parsing: |
166 * @since 1.1 |
166 * @since 1.1 |
167 */ |
167 */ |
168 public class ChoiceFormat extends NumberFormat { |
168 public class ChoiceFormat extends NumberFormat { |
169 |
169 |
170 // Proclaim serial compatibility with 1.1 FCS |
170 // Proclaim serial compatibility with 1.1 FCS |
|
171 @java.io.Serial |
171 private static final long serialVersionUID = 1795184449645032964L; |
172 private static final long serialVersionUID = 1795184449645032964L; |
172 |
173 |
173 /** |
174 /** |
174 * Sets the pattern. |
175 * Sets the pattern. |
175 * @param newPattern See the class description. |
176 * @param newPattern See the class description. |
176 * @exception NullPointerException if {@code newPattern} |
177 * @throws NullPointerException if {@code newPattern} |
177 * is {@code null} |
178 * is {@code null} |
178 */ |
179 */ |
179 public void applyPattern(String newPattern) { |
180 public void applyPattern(String newPattern) { |
180 StringBuffer[] segments = new StringBuffer[2]; |
181 StringBuffer[] segments = new StringBuffer[2]; |
181 for (int i = 0; i < segments.length; ++i) { |
182 for (int i = 0; i < segments.length; ++i) { |
323 /** |
324 /** |
324 * Constructs with the limits and the corresponding formats. |
325 * Constructs with the limits and the corresponding formats. |
325 * |
326 * |
326 * @param limits limits in ascending order |
327 * @param limits limits in ascending order |
327 * @param formats corresponding format strings |
328 * @param formats corresponding format strings |
328 * @exception NullPointerException if {@code limits} or {@code formats} |
329 * @throws NullPointerException if {@code limits} or {@code formats} |
329 * is {@code null} |
330 * is {@code null} |
330 * @see #setChoices |
331 * @see #setChoices |
331 */ |
332 */ |
332 public ChoiceFormat(double[] limits, String[] formats) { |
333 public ChoiceFormat(double[] limits, String[] formats) { |
333 setChoices(limits, formats); |
334 setChoices(limits, formats); |
344 * @param formats are the formats you want to use for each limit. |
345 * @param formats are the formats you want to use for each limit. |
345 * They can be either Format objects or Strings. |
346 * They can be either Format objects or Strings. |
346 * When formatting with object Y, |
347 * When formatting with object Y, |
347 * if the object is a NumberFormat, then ((NumberFormat) Y).format(X) |
348 * if the object is a NumberFormat, then ((NumberFormat) Y).format(X) |
348 * is called. Otherwise Y.toString() is called. |
349 * is called. Otherwise Y.toString() is called. |
349 * @exception NullPointerException if {@code limits} or |
350 * @throws NullPointerException if {@code limits} or |
350 * {@code formats} is {@code null} |
351 * {@code formats} is {@code null} |
351 */ |
352 */ |
352 public void setChoices(double[] limits, String formats[]) { |
353 public void setChoices(double[] limits, String formats[]) { |
353 if (limits.length != formats.length) { |
354 if (limits.length != formats.length) { |
354 throw new IllegalArgumentException( |
355 throw new IllegalArgumentException( |
378 |
379 |
379 // Overrides |
380 // Overrides |
380 |
381 |
381 /** |
382 /** |
382 * Specialization of format. This method really calls |
383 * Specialization of format. This method really calls |
383 * <code>format(double, StringBuffer, FieldPosition)</code> |
384 * {@code format(double, StringBuffer, FieldPosition)} |
384 * thus the range of longs that are supported is only equal to |
385 * thus the range of longs that are supported is only equal to |
385 * the range that can be stored by double. This will never be |
386 * the range that can be stored by double. This will never be |
386 * a practical limitation. |
387 * a practical limitation. |
387 */ |
388 */ |
388 public StringBuffer format(long number, StringBuffer toAppendTo, |
389 public StringBuffer format(long number, StringBuffer toAppendTo, |
393 /** |
394 /** |
394 * Returns pattern with formatted double. |
395 * Returns pattern with formatted double. |
395 * @param number number to be formatted and substituted. |
396 * @param number number to be formatted and substituted. |
396 * @param toAppendTo where text is appended. |
397 * @param toAppendTo where text is appended. |
397 * @param status ignore no useful status is returned. |
398 * @param status ignore no useful status is returned. |
398 * @exception NullPointerException if {@code toAppendTo} |
399 * @throws NullPointerException if {@code toAppendTo} |
399 * is {@code null} |
400 * is {@code null} |
400 */ |
401 */ |
401 public StringBuffer format(double number, StringBuffer toAppendTo, |
402 public StringBuffer format(double number, StringBuffer toAppendTo, |
402 FieldPosition status) { |
403 FieldPosition status) { |
403 // find the number |
404 // find the number |
423 * occurred, status.index is set to the first unparsed character |
424 * occurred, status.index is set to the first unparsed character |
424 * in the source text. On exit, if an error did occur, |
425 * in the source text. On exit, if an error did occur, |
425 * status.index is unchanged and status.errorIndex is set to the |
426 * status.index is unchanged and status.errorIndex is set to the |
426 * first index of the character that caused the parse to fail. |
427 * first index of the character that caused the parse to fail. |
427 * @return A Number representing the value of the number parsed. |
428 * @return A Number representing the value of the number parsed. |
428 * @exception NullPointerException if {@code status} is {@code null} |
429 * @throws NullPointerException if {@code status} is {@code null} |
429 * or if {@code text} is {@code null} and the list of |
430 * or if {@code text} is {@code null} and the list of |
430 * choice strings is not empty. |
431 * choice strings is not empty. |
431 */ |
432 */ |
432 public Number parse(String text, ParsePosition status) { |
433 public Number parse(String text, ParsePosition status) { |
433 // find the best number (defined as the one with the longest parse) |
434 // find the best number (defined as the one with the longest parse) |
526 /** |
527 /** |
527 * After reading an object from the input stream, do a simple verification |
528 * After reading an object from the input stream, do a simple verification |
528 * to maintain class invariants. |
529 * to maintain class invariants. |
529 * @throws InvalidObjectException if the objects read from the stream is invalid. |
530 * @throws InvalidObjectException if the objects read from the stream is invalid. |
530 */ |
531 */ |
|
532 @java.io.Serial |
531 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { |
533 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { |
532 in.defaultReadObject(); |
534 in.defaultReadObject(); |
533 if (choiceLimits.length != choiceFormats.length) { |
535 if (choiceLimits.length != choiceFormats.length) { |
534 throw new InvalidObjectException( |
536 throw new InvalidObjectException( |
535 "limits and format arrays of different length."); |
537 "limits and format arrays of different length."); |
538 |
540 |
539 // ===============privates=========================== |
541 // ===============privates=========================== |
540 |
542 |
541 /** |
543 /** |
542 * A list of lower bounds for the choices. The formatter will return |
544 * A list of lower bounds for the choices. The formatter will return |
543 * <code>choiceFormats[i]</code> if the number being formatted is greater than or equal to |
545 * {@code choiceFormats[i]} if the number being formatted is greater than or equal to |
544 * <code>choiceLimits[i]</code> and less than <code>choiceLimits[i+1]</code>. |
546 * {@code choiceLimits[i]} and less than {@code choiceLimits[i+1]}. |
545 * @serial |
547 * @serial |
546 */ |
548 */ |
547 private double[] choiceLimits; |
549 private double[] choiceLimits; |
548 |
550 |
549 /** |
551 /** |
550 * A list of choice strings. The formatter will return |
552 * A list of choice strings. The formatter will return |
551 * <code>choiceFormats[i]</code> if the number being formatted is greater than or equal to |
553 * {@code choiceFormats[i]} if the number being formatted is greater than or equal to |
552 * <code>choiceLimits[i]</code> and less than <code>choiceLimits[i+1]</code>. |
554 * {@code choiceLimits[i]} and less than {@code choiceLimits[i+1]}. |
553 * @serial |
555 * @serial |
554 */ |
556 */ |
555 private String[] choiceFormats; |
557 private String[] choiceFormats; |
556 |
558 |
557 /** |
559 /** |