LEFT | RIGHT |
1 // © 2017 and later: Unicode, Inc. and others. | 1 // © 2017 and later: Unicode, Inc. and others. |
2 // License & terms of use: http://www.unicode.org/copyright.html#License | 2 // License & terms of use: http://www.unicode.org/copyright.html#License |
3 package com.ibm.icu.text; | 3 package com.ibm.icu.text; |
4 | 4 |
| 5 import java.io.IOException; |
| 6 import java.io.ObjectInputStream; |
| 7 import java.io.ObjectOutputStream; |
| 8 import java.io.ObjectStreamField; |
5 import java.math.BigInteger; | 9 import java.math.BigInteger; |
6 import java.math.RoundingMode; | 10 import java.math.RoundingMode; |
7 import java.text.AttributedCharacterIterator; | 11 import java.text.AttributedCharacterIterator; |
8 import java.text.FieldPosition; | 12 import java.text.FieldPosition; |
9 import java.text.ParseException; | 13 import java.text.ParseException; |
10 import java.text.ParsePosition; | 14 import java.text.ParsePosition; |
11 | 15 |
| 16 import com.ibm.icu.impl.number.AffixPatternUtils; |
12 import com.ibm.icu.impl.number.Endpoint; | 17 import com.ibm.icu.impl.number.Endpoint; |
13 import com.ibm.icu.impl.number.Format.SingularFormat; | 18 import com.ibm.icu.impl.number.Format.SingularFormat; |
14 import com.ibm.icu.impl.number.FormatQuantity; | |
15 import com.ibm.icu.impl.number.FormatQuantity4; | 19 import com.ibm.icu.impl.number.FormatQuantity4; |
16 import com.ibm.icu.impl.number.FormatQuantitySelector; | |
17 import com.ibm.icu.impl.number.Parse; | 20 import com.ibm.icu.impl.number.Parse; |
18 import com.ibm.icu.impl.number.PatternString; | 21 import com.ibm.icu.impl.number.PatternString; |
19 import com.ibm.icu.impl.number.Properties; | 22 import com.ibm.icu.impl.number.Properties; |
20 import com.ibm.icu.impl.number.formatters.PaddingFormat.PaddingLocation; | 23 import com.ibm.icu.impl.number.formatters.PaddingFormat.PadPosition; |
21 import com.ibm.icu.impl.number.formatters.PositiveDecimalFormat; | 24 import com.ibm.icu.impl.number.formatters.PositiveDecimalFormat; |
22 import com.ibm.icu.impl.number.formatters.ScientificFormat; | 25 import com.ibm.icu.impl.number.formatters.ScientificFormat; |
23 import com.ibm.icu.impl.number.rounders.SignificantDigitsRounder; | 26 import com.ibm.icu.impl.number.rounders.SignificantDigitsRounder; |
| 27 import com.ibm.icu.impl.number.rounders.SignificantDigitsRounder.SignificantDigi
tsMode; |
| 28 import com.ibm.icu.lang.UCharacter; |
24 import com.ibm.icu.math.BigDecimal; | 29 import com.ibm.icu.math.BigDecimal; |
25 import com.ibm.icu.math.MathContext; | 30 import com.ibm.icu.math.MathContext; |
26 import com.ibm.icu.text.PluralRules.IFixedDecimal; | 31 import com.ibm.icu.text.PluralRules.IFixedDecimal; |
27 import com.ibm.icu.text.PluralRules.Operand; | |
28 import com.ibm.icu.util.Currency; | 32 import com.ibm.icu.util.Currency; |
29 import com.ibm.icu.util.Currency.CurrencyUsage; | 33 import com.ibm.icu.util.Currency.CurrencyUsage; |
30 import com.ibm.icu.util.CurrencyAmount; | 34 import com.ibm.icu.util.CurrencyAmount; |
31 | 35 import com.ibm.icu.util.ULocale; |
32 /** @author sffc */ | 36 |
| 37 /** @stable ICU 2.0 */ |
33 public class DecimalFormat extends NumberFormat { | 38 public class DecimalFormat extends NumberFormat { |
34 | 39 |
35 private final Properties properties; | 40 /** New serialization in ICU 59: declare different version from ICU 58. */ |
36 private volatile DecimalFormatSymbols symbols; | 41 private static final long serialVersionUID = 864413376551465018L; |
37 private transient volatile SingularFormat formatter; | 42 |
| 43 /** |
| 44 * One non-transient field such that deserialization can determine the version
of the class. This |
| 45 * field has existed since the very earliest versions of DecimalFormat. |
| 46 */ |
| 47 @SuppressWarnings("unused") |
| 48 private final int serialVersionOnStream = 5; |
| 49 |
| 50 //============================================================================
=========// |
| 51 // INSTANCE FIELDS
// |
| 52 //============================================================================
=========// |
| 53 |
| 54 // Fields are package-private, so that subclasses can use them. |
| 55 // properties should be final, but clone won't work if we make it final. |
| 56 // All fields are transient because custom serialization is used. |
| 57 |
| 58 /** |
| 59 * The property bag corresponding to user-specified settings and settings from
the pattern string. |
| 60 * In principle this should be final, but serialize and clone won't work if it
is final. Does not |
| 61 * need to be volatile because the reference never changes. |
| 62 */ |
| 63 /* final */ transient Properties properties; |
| 64 |
| 65 /** |
| 66 * The symbols for the current locale. Volatile because threads may read and w
rite at the same |
| 67 * time. |
| 68 */ |
| 69 transient volatile DecimalFormatSymbols symbols; |
| 70 |
| 71 /** |
| 72 * The pre-computed formatter object. Setters cause this to be re-computed ato
mically. The {@link |
| 73 * #format} method uses the formatter directly without needing to synchronize.
Volatile because |
| 74 * threads may read and write at the same time. |
| 75 */ |
| 76 transient volatile SingularFormat formatter; |
| 77 |
| 78 /** |
| 79 * The effective properties as exported from the formatter object. Volatile be
cause threads may |
| 80 * read and write at the same time. |
| 81 */ |
| 82 transient volatile Properties exportedProperties; |
| 83 |
| 84 //============================================================================
=========// |
| 85 // CONSTRUCTORS
// |
| 86 //============================================================================
=========// |
38 | 87 |
39 /** @stable ICU 2.0 */ | 88 /** @stable ICU 2.0 */ |
40 public DecimalFormat() { | 89 public DecimalFormat() { |
| 90 // Use the locale's default pattern |
| 91 ULocale def = ULocale.getDefault(ULocale.Category.FORMAT); |
| 92 String pattern = getPattern(def, 0); |
41 symbols = getDefaultSymbols(); | 93 symbols = getDefaultSymbols(); |
42 properties = new Properties(); | 94 properties = new Properties(); |
| 95 exportedProperties = new Properties(); |
| 96 // Regression: ignore pattern rounding information if the pattern has curren
cy symbols. |
| 97 boolean ignorePatternRounding = AffixPatternUtils.hasCurrencySymbols(pattern
); |
| 98 setPropertiesFromPattern(pattern, ignorePatternRounding); |
43 refreshFormatter(); | 99 refreshFormatter(); |
44 } | 100 } |
45 | 101 |
46 /** @stable ICU 2.0 */ | 102 /** @stable ICU 2.0 */ |
47 public DecimalFormat(String pattern) { | 103 public DecimalFormat(String pattern) { |
48 symbols = getDefaultSymbols(); | 104 symbols = getDefaultSymbols(); |
49 properties = new Properties(); | 105 properties = new Properties(); |
50 setPropertiesFromPattern(pattern); | 106 exportedProperties = new Properties(); |
| 107 // Regression: ignore pattern rounding information if the pattern has curren
cy symbols. |
| 108 boolean ignorePatternRounding = AffixPatternUtils.hasCurrencySymbols(pattern
); |
| 109 setPropertiesFromPattern(pattern, ignorePatternRounding); |
51 refreshFormatter(); | 110 refreshFormatter(); |
52 } | 111 } |
53 | 112 |
54 /** @stable ICU 2.0 */ | 113 /** @stable ICU 2.0 */ |
55 public DecimalFormat(String pattern, DecimalFormatSymbols symbols) { | 114 public DecimalFormat(String pattern, DecimalFormatSymbols symbols) { |
56 this.symbols = (DecimalFormatSymbols) symbols.clone(); | 115 this.symbols = (DecimalFormatSymbols) symbols.clone(); |
57 properties = new Properties(); | 116 properties = new Properties(); |
58 setPropertiesFromPattern(pattern); | 117 exportedProperties = new Properties(); |
| 118 // Regression: ignore pattern rounding information if the pattern has curren
cy symbols. |
| 119 boolean ignorePatternRounding = AffixPatternUtils.hasCurrencySymbols(pattern
); |
| 120 setPropertiesFromPattern(pattern, ignorePatternRounding); |
59 refreshFormatter(); | 121 refreshFormatter(); |
60 } | 122 } |
61 | 123 |
62 /** @stable ICU 4.2 */ | 124 /** @stable ICU 4.2 */ |
63 public DecimalFormat( | 125 public DecimalFormat( |
64 String pattern, DecimalFormatSymbols symbols, CurrencyPluralInfo infoInput
, int style) { | 126 String pattern, DecimalFormatSymbols symbols, CurrencyPluralInfo infoInput
, int style) { |
65 this.symbols = (DecimalFormatSymbols) symbols.clone(); | 127 this.symbols = (DecimalFormatSymbols) symbols.clone(); |
66 properties = new Properties(); | 128 properties = new Properties(); |
| 129 exportedProperties = new Properties(); |
67 properties.setCurrencyPluralInfo(infoInput); | 130 properties.setCurrencyPluralInfo(infoInput); |
68 refreshFormatter(); | |
69 } | |
70 | |
71 private DecimalFormat(DecimalFormat other) { | |
72 symbols = (DecimalFormatSymbols) other.symbols.clone(); | |
73 properties = other.properties.clone(); | |
74 refreshFormatter(); | 131 refreshFormatter(); |
75 } | 132 } |
76 | 133 |
77 /** Package-private constructor used by NumberFormat. */ | 134 /** Package-private constructor used by NumberFormat. */ |
78 DecimalFormat(String pattern, DecimalFormatSymbols symbols, int choice) { | 135 DecimalFormat(String pattern, DecimalFormatSymbols symbols, int choice) { |
79 this.symbols = (DecimalFormatSymbols) symbols.clone(); | 136 this.symbols = (DecimalFormatSymbols) symbols.clone(); |
80 properties = new Properties(); | 137 properties = new Properties(); |
81 setPropertiesFromPattern(pattern); | 138 exportedProperties = new Properties(); |
82 // HACK: If choice is a currency type, unset the rounding information. | 139 // If choice is a currency type, ignore the rounding information. |
83 if (choice == NumberFormat.CURRENCYSTYLE | 140 if (choice == CURRENCYSTYLE |
84 || choice == NumberFormat.ISOCURRENCYSTYLE | 141 || choice == ISOCURRENCYSTYLE |
85 || choice == NumberFormat.PLURALCURRENCYSTYLE){ | 142 || choice == ACCOUNTINGCURRENCYSTYLE |
86 properties.setMinimumFractionDigits(Properties.DEFAULT_MINIMUM_FRACTION_DI
GITS); | 143 || choice == CASHCURRENCYSTYLE |
87 properties.setMaximumFractionDigits(Properties.DEFAULT_MAXIMUM_FRACTION_DI
GITS); | 144 || choice == STANDARDCURRENCYSTYLE |
88 properties.setRoundingInterval(Properties.DEFAULT_ROUNDING_INTERVAL); | 145 || choice == PLURALCURRENCYSTYLE |
| 146 || AffixPatternUtils.hasCurrencySymbols(pattern)) { |
| 147 setPropertiesFromPattern(pattern, true); |
| 148 } else { |
| 149 setPropertiesFromPattern(pattern, false); |
89 } | 150 } |
90 // FIXME: Deal with choice | |
91 // switch (choice) { | |
92 // case NumberFormat.PLURALCURRENCYSTYLE: | |
93 // properties.setCurrencyStyle(CurrencyStyle.PLURAL); | |
94 // break; | |
95 // } | |
96 refreshFormatter(); | 151 refreshFormatter(); |
97 } | 152 } |
98 | 153 |
99 private static DecimalFormatSymbols getDefaultSymbols() { | 154 private static DecimalFormatSymbols getDefaultSymbols() { |
100 return DecimalFormatSymbols.getInstance(); | 155 return DecimalFormatSymbols.getInstance(); |
101 } | 156 } |
102 | 157 |
103 /** @stable ICU 2.0 */ | 158 /** |
| 159 * Parses the given pattern string and overwrites the settings specified in th
e pattern string. |
| 160 * The properties corresponding to the following setters are overwritten, eith
er with their |
| 161 * default values or with the value specified in the pattern string: |
| 162 * |
| 163 * <ol> |
| 164 * <li>{@link #setDecimalSeparatorAlwaysShown} |
| 165 * <li>{@link #setExponentSignAlwaysShown} |
| 166 * <li>{@link #setFormatWidth} |
| 167 * <li>{@link #setGroupingSize} |
| 168 * <li>{@link #setMultiplier} (percent/permille) |
| 169 * <li>{@link #setMaximumFractionDigits} |
| 170 * <li>{@link #setMaximumIntegerDigits} |
| 171 * <li>{@link #setMaximumSignificantDigits} |
| 172 * <li>{@link #setMinimumExponentDigits} |
| 173 * <li>{@link #setMinimumFractionDigits} |
| 174 * <li>{@link #setMinimumIntegerDigits} |
| 175 * <li>{@link #setMinimumSignificantDigits} |
| 176 * <li>{@link #setPadPosition} |
| 177 * <li>{@link #setPadCharacter} |
| 178 * <li>{@link #setRoundingIncrement} |
| 179 * <li>{@link #setSecondaryGroupingSize} |
| 180 * </ol> |
| 181 * |
| 182 * All other settings remain untouched. |
| 183 * |
| 184 * <p>For more information on pattern strings, see <a |
| 185 * href="http://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patte
rns">UTS #35</a>. |
| 186 * |
| 187 * @stable ICU 2.0 |
| 188 */ |
104 public synchronized void applyPattern(String pattern) { | 189 public synchronized void applyPattern(String pattern) { |
105 setPropertiesFromPattern(pattern); | 190 setPropertiesFromPattern(pattern, false); |
106 // Backwards compatibility: clear out user-specified prefix and suffix | 191 // Backwards compatibility: clear out user-specified prefix and suffix, |
| 192 // as well as CurrencyPluralInfo. |
107 properties.setPositivePrefix(null); | 193 properties.setPositivePrefix(null); |
108 properties.setNegativePrefix(null); | 194 properties.setNegativePrefix(null); |
109 properties.setPositiveSuffix(null); | 195 properties.setPositiveSuffix(null); |
110 properties.setNegativeSuffix(null); | 196 properties.setNegativeSuffix(null); |
111 refreshFormatter(); | 197 properties.setCurrencyPluralInfo(null); |
112 } | 198 refreshFormatter(); |
113 | 199 } |
114 /** @stable ICU 2.0 */ | 200 |
| 201 /** |
| 202 * Converts the given string to standard notation and then parses it using {@l
ink #applyPattern}. |
| 203 * |
| 204 * <p>Localized notation means that instead of using generic placeholders in t
he pattern, you use |
| 205 * the corresponding locale-specific characters instead. For example, in local
e <em>fr-FR</em>, |
| 206 * the period in the pattern "0.000" means "decimal" in standard notation (as
it does in every |
| 207 * other locale), but it means "grouping" in localized notation. |
| 208 * |
| 209 * @param localizedPattern The pattern string in localized notation. |
| 210 * @stable ICU 2.0 |
| 211 */ |
115 public synchronized void applyLocalizedPattern(String localizedPattern) { | 212 public synchronized void applyLocalizedPattern(String localizedPattern) { |
116 String pattern = PatternString.convertLocalized(localizedPattern, symbols, f
alse); | 213 String pattern = PatternString.convertLocalized(localizedPattern, symbols, f
alse); |
117 applyPattern(pattern); | 214 applyPattern(pattern); |
118 } | 215 } |
119 | 216 |
120 /** | 217 //============================================================================
=========// |
121 * {@inheritDoc} | 218 // CLONE AND SERIALIZE
// |
122 * | 219 //============================================================================
=========// |
123 * @stable ICU 2.0 | 220 |
124 */ | 221 /** @stable ICU 2.0 */ |
| 222 @Override |
| 223 public Object clone() { |
| 224 DecimalFormat other = (DecimalFormat) super.clone(); |
| 225 other.symbols = (DecimalFormatSymbols) symbols.clone(); |
| 226 other.properties = properties.clone(); |
| 227 other.exportedProperties = new Properties(); |
| 228 other.refreshFormatter(); |
| 229 return other; |
| 230 } |
| 231 |
| 232 /** |
| 233 * Custom serialization: save property bag and symbols; the formatter object c
an be re-created |
| 234 * from just that amount of information. |
| 235 */ |
| 236 private void writeObject(ObjectOutputStream oos) throws IOException { |
| 237 // ICU 59 custom serialization. |
| 238 // Write class metadata and serialVersionOnStream field: |
| 239 oos.defaultWriteObject(); |
| 240 // Extra int for possible future use: |
| 241 oos.writeInt(0); |
| 242 // 1) Property Bag |
| 243 oos.writeObject(properties); |
| 244 // 2) DecimalFormatSymbols |
| 245 oos.writeObject(symbols); |
| 246 } |
| 247 |
| 248 /** |
| 249 * Custom serialization: re-create object from serialized property bag and sym
bols. Also supports |
| 250 * reading from the legacy (pre-ICU4J 59) format and converting it to the new
form. |
| 251 */ |
| 252 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFou
ndException { |
| 253 ObjectInputStream.GetField fieldGetter = ois.readFields(); |
| 254 ObjectStreamField[] serializedFields = fieldGetter.getObjectStreamClass().ge
tFields(); |
| 255 int serialVersion = fieldGetter.get("serialVersionOnStream", -1); |
| 256 |
| 257 if (serialVersion > 5) { |
| 258 throw new IOException( |
| 259 "Cannot deserialize newer com.ibm.icu.text.DecimalFormat (v" + serialV
ersion + ")"); |
| 260 } else if (serialVersion == 5) { |
| 261 ///// ICU 59+ SERIALIZATION FORMAT ///// |
| 262 // We expect this field and no other fields: |
| 263 if (serializedFields.length > 1) { |
| 264 throw new IOException("Too many fields when reading serial version 5"); |
| 265 } |
| 266 // Extra int for possible future use: |
| 267 ois.readInt(); |
| 268 // 1) Property Bag |
| 269 properties = (Properties) ois.readObject(); |
| 270 // 2) DecimalFormatSymbols |
| 271 symbols = (DecimalFormatSymbols) ois.readObject(); |
| 272 // Re-build transient fields |
| 273 exportedProperties = new Properties(); |
| 274 refreshFormatter(); |
| 275 } else { |
| 276 ///// LEGACY SERIALIZATION FORMAT ///// |
| 277 properties = new Properties(); |
| 278 // Loop through the fields. Not all fields necessarily exist in the serial
ization. |
| 279 String pp = null, ppp = null, ps = null, psp = null; |
| 280 String np = null, npp = null, ns = null, nsp = null; |
| 281 for (ObjectStreamField field : serializedFields) { |
| 282 String name = field.getName(); |
| 283 if (name.equals("decimalSeparatorAlwaysShown")) { |
| 284 setDecimalSeparatorAlwaysShown(fieldGetter.get("decimalSeparatorAlways
Shown", false)); |
| 285 } else if (name.equals("exponentSignAlwaysShown")) { |
| 286 setExponentSignAlwaysShown(fieldGetter.get("exponentSignAlwaysShown",
false)); |
| 287 } else if (name.equals("formatWidth")) { |
| 288 setFormatWidth(fieldGetter.get("formatWidth", 0)); |
| 289 } else if (name.equals("groupingSize")) { |
| 290 setGroupingSize(fieldGetter.get("groupingSize", (byte) 3)); |
| 291 } else if (name.equals("groupingSize2")) { |
| 292 setSecondaryGroupingSize(fieldGetter.get("groupingSize2", (byte) 0)); |
| 293 } else if (name.equals("maxSignificantDigits")) { |
| 294 setMaximumSignificantDigits(fieldGetter.get("maxSignificantDigits", 6)
); |
| 295 } else if (name.equals("minExponentDigits")) { |
| 296 setMinimumExponentDigits(fieldGetter.get("minExponentDigits", (byte) 0
)); |
| 297 } else if (name.equals("minSignificantDigits")) { |
| 298 setMinimumSignificantDigits(fieldGetter.get("minSignificantDigits", 1)
); |
| 299 } else if (name.equals("multiplier")) { |
| 300 setMultiplier(fieldGetter.get("multiplier", 1)); |
| 301 } else if (name.equals("pad")) { |
| 302 setPadCharacter(fieldGetter.get("pad", '\u0020')); |
| 303 } else if (name.equals("padPosition")) { |
| 304 setPadPosition(fieldGetter.get("padPosition", 0)); |
| 305 } else if (name.equals("parseBigDecimal")) { |
| 306 setParseBigDecimal(fieldGetter.get("parseBigDecimal", false)); |
| 307 } else if (name.equals("parseRequireDecimalPoint")) { |
| 308 setDecimalPatternMatchRequired(fieldGetter.get("parseRequireDecimalPoi
nt", false)); |
| 309 } else if (name.equals("roundingMode")) { |
| 310 setRoundingMode(fieldGetter.get("roundingMode", 0)); |
| 311 } else if (name.equals("useExponentialNotation")) { |
| 312 setScientificNotation(fieldGetter.get("useExponentialNotation", false)
); |
| 313 } else if (name.equals("useSignificantDigits")) { |
| 314 setSignificantDigitsUsed(fieldGetter.get("useSignificantDigits", false
)); |
| 315 } else if (name.equals("currencyPluralInfo")) { |
| 316 setCurrencyPluralInfo((CurrencyPluralInfo) fieldGetter.get("currencyPl
uralInfo", null)); |
| 317 } else if (name.equals("currencyUsage")) { |
| 318 setCurrencyUsage((CurrencyUsage) fieldGetter.get("currencyUsage", null
)); |
| 319 } else if (name.equals("mathContext")) { |
| 320 setMathContextICU((MathContext) fieldGetter.get("mathContext", null)); |
| 321 } else if (name.equals("negPrefixPattern")) { |
| 322 npp = (String) fieldGetter.get("negPrefixPattern", null); |
| 323 } else if (name.equals("negSuffixPattern")) { |
| 324 nsp = (String) fieldGetter.get("negSuffixPattern", null); |
| 325 } else if (name.equals("negativePrefix")) { |
| 326 np = (String) fieldGetter.get("negativePrefix", null); |
| 327 } else if (name.equals("negativeSuffix")) { |
| 328 ns = (String) fieldGetter.get("negativeSuffix", null); |
| 329 } else if (name.equals("posPrefixPattern")) { |
| 330 ppp = (String) fieldGetter.get("posPrefixPattern", null); |
| 331 } else if (name.equals("posSuffixPattern")) { |
| 332 psp = (String) fieldGetter.get("posSuffixPattern", null); |
| 333 } else if (name.equals("positivePrefix")) { |
| 334 pp = (String) fieldGetter.get("positivePrefix", null); |
| 335 } else if (name.equals("positiveSuffix")) { |
| 336 ps = (String) fieldGetter.get("positiveSuffix", null); |
| 337 } else if (name.equals("roundingIncrement")) { |
| 338 setRoundingIncrement((java.math.BigDecimal) fieldGetter.get("roundingI
ncrement", null)); |
| 339 } else if (name.equals("symbols")) { |
| 340 setDecimalFormatSymbols((DecimalFormatSymbols) fieldGetter.get("symbol
s", null)); |
| 341 } else { |
| 342 // The following fields are ignored: |
| 343 // "PARSE_MAX_EXPONENT" |
| 344 // "currencySignCount" |
| 345 // "style" |
| 346 // "attributes" |
| 347 // "currencyChoice" |
| 348 // "formatPattern" |
| 349 } |
| 350 } |
| 351 // Resolve affixes |
| 352 if (npp == null) { |
| 353 properties.setNegativePrefix(np); |
| 354 } else { |
| 355 properties.setNegativePrefixPattern(npp); |
| 356 } |
| 357 if (nsp == null) { |
| 358 properties.setNegativeSuffix(ns); |
| 359 } else { |
| 360 properties.setNegativeSuffixPattern(nsp); |
| 361 } |
| 362 if (ppp == null) { |
| 363 properties.setPositivePrefix(pp); |
| 364 } else { |
| 365 properties.setPositivePrefixPattern(ppp); |
| 366 } |
| 367 if (psp == null) { |
| 368 properties.setPositiveSuffix(ps); |
| 369 } else { |
| 370 properties.setPositiveSuffixPattern(psp); |
| 371 } |
| 372 // Extract values from parent NumberFormat class. Have to use reflection
here. |
| 373 java.lang.reflect.Field getter; |
| 374 try { |
| 375 getter = NumberFormat.class.getDeclaredField("groupingUsed"); |
| 376 getter.setAccessible(true); |
| 377 setGroupingUsed((Boolean) getter.get(this)); |
| 378 getter = NumberFormat.class.getDeclaredField("parseIntegerOnly"); |
| 379 getter.setAccessible(true); |
| 380 setParseIntegerOnly((Boolean) getter.get(this)); |
| 381 getter = NumberFormat.class.getDeclaredField("maximumIntegerDigits"); |
| 382 getter.setAccessible(true); |
| 383 setMaximumIntegerDigits((Integer) getter.get(this)); |
| 384 getter = NumberFormat.class.getDeclaredField("minimumIntegerDigits"); |
| 385 getter.setAccessible(true); |
| 386 setMinimumIntegerDigits((Integer) getter.get(this)); |
| 387 getter = NumberFormat.class.getDeclaredField("maximumFractionDigits"); |
| 388 getter.setAccessible(true); |
| 389 setMaximumFractionDigits((Integer) getter.get(this)); |
| 390 getter = NumberFormat.class.getDeclaredField("minimumFractionDigits"); |
| 391 getter.setAccessible(true); |
| 392 setMinimumFractionDigits((Integer) getter.get(this)); |
| 393 getter = NumberFormat.class.getDeclaredField("currency"); |
| 394 getter.setAccessible(true); |
| 395 setCurrency((Currency) getter.get(this)); |
| 396 getter = NumberFormat.class.getDeclaredField("parseStrict"); |
| 397 getter.setAccessible(true); |
| 398 setParseStrict((Boolean) getter.get(this)); |
| 399 } catch (IllegalArgumentException e) { |
| 400 throw new IOException(e); |
| 401 } catch (IllegalAccessException e) { |
| 402 throw new IOException(e); |
| 403 } catch (NoSuchFieldException e) { |
| 404 throw new IOException(e); |
| 405 } catch (SecurityException e) { |
| 406 throw new IOException(e); |
| 407 } |
| 408 // Finish initialization |
| 409 if (symbols == null) { |
| 410 symbols = getDefaultSymbols(); |
| 411 } |
| 412 exportedProperties = new Properties(); |
| 413 refreshFormatter(); |
| 414 } |
| 415 } |
| 416 |
| 417 //============================================================================
=========// |
| 418 // FORMAT AND PARSE APIS
// |
| 419 //============================================================================
=========// |
| 420 |
| 421 /** @stable ICU 2.0 */ |
125 @Override | 422 @Override |
126 public StringBuffer format(double number, StringBuffer result, FieldPosition f
ieldPosition) { | 423 public StringBuffer format(double number, StringBuffer result, FieldPosition f
ieldPosition) { |
127 FormatQuantity fq = new FormatQuantity4(number); | 424 FormatQuantity4 fq = new FormatQuantity4(number); |
128 formatter.format(fq, result, fieldPosition); | 425 formatter.format(fq, result, fieldPosition); |
129 populateUFieldPosition(fq, fieldPosition); | 426 fq.populateUFieldPosition(fieldPosition); |
130 return result; | 427 return result; |
131 } | 428 } |
132 | 429 |
133 /** @stable ICU 2.0 */ | 430 /** @stable ICU 2.0 */ |
134 @Override | 431 @Override |
135 public StringBuffer format(long number, StringBuffer result, FieldPosition fie
ldPosition) { | 432 public StringBuffer format(long number, StringBuffer result, FieldPosition fie
ldPosition) { |
136 FormatQuantity fq = new FormatQuantity4(number); | 433 FormatQuantity4 fq = new FormatQuantity4(number); |
137 formatter.format(fq, result, fieldPosition); | 434 formatter.format(fq, result, fieldPosition); |
138 populateUFieldPosition(fq, fieldPosition); | 435 fq.populateUFieldPosition(fieldPosition); |
139 return result; | 436 return result; |
140 } | 437 } |
141 | 438 |
142 /** @stable ICU 2.0 */ | 439 /** @stable ICU 2.0 */ |
143 @Override | 440 @Override |
144 public StringBuffer format(BigInteger number, StringBuffer result, FieldPositi
on fieldPosition) { | 441 public StringBuffer format(BigInteger number, StringBuffer result, FieldPositi
on fieldPosition) { |
145 FormatQuantity fq = new FormatQuantity4(number); | 442 FormatQuantity4 fq = new FormatQuantity4(number); |
146 formatter.format(fq, result, fieldPosition); | 443 formatter.format(fq, result, fieldPosition); |
147 populateUFieldPosition(fq, fieldPosition); | 444 fq.populateUFieldPosition(fieldPosition); |
148 return result; | 445 return result; |
149 } | 446 } |
150 | 447 |
151 /** @stable ICU 2.0 */ | 448 /** @stable ICU 2.0 */ |
152 @Override | 449 @Override |
153 public StringBuffer format( | 450 public StringBuffer format( |
154 java.math.BigDecimal number, StringBuffer result, FieldPosition fieldPosit
ion) { | 451 java.math.BigDecimal number, StringBuffer result, FieldPosition fieldPosit
ion) { |
155 FormatQuantity fq = new FormatQuantity4(number); | 452 FormatQuantity4 fq = new FormatQuantity4(number); |
156 formatter.format(fq, result, fieldPosition); | 453 formatter.format(fq, result, fieldPosition); |
157 populateUFieldPosition(fq, fieldPosition); | 454 fq.populateUFieldPosition(fieldPosition); |
158 return result; | 455 return result; |
159 } | 456 } |
160 | 457 |
161 /** @stable ICU 2.0 */ | 458 /** @stable ICU 2.0 */ |
162 @Override | 459 @Override |
163 public StringBuffer format(BigDecimal number, StringBuffer result, FieldPositi
on fieldPosition) { | 460 public StringBuffer format(BigDecimal number, StringBuffer result, FieldPositi
on fieldPosition) { |
164 FormatQuantity fq = new FormatQuantity4(number.toBigDecimal()); | 461 FormatQuantity4 fq = new FormatQuantity4(number.toBigDecimal()); |
165 formatter.format(fq, result, fieldPosition); | 462 formatter.format(fq, result, fieldPosition); |
166 populateUFieldPosition(fq, fieldPosition); | 463 fq.populateUFieldPosition(fieldPosition); |
167 return result; | 464 return result; |
| 465 } |
| 466 |
| 467 /** @stable ICU 3.6 */ |
| 468 @Override |
| 469 public AttributedCharacterIterator formatToCharacterIterator(Object obj) { |
| 470 if (!(obj instanceof Number)) throw new IllegalArgumentException(); |
| 471 Number number = (Number) obj; |
| 472 FormatQuantity4 fq = new FormatQuantity4(number); |
| 473 AttributedCharacterIterator result = formatter.formatToCharacterIterator(fq)
; |
| 474 return result; |
| 475 } |
| 476 |
| 477 protected static final ThreadLocal<Properties> threadLocalCurrencyProperties = |
| 478 new ThreadLocal<Properties>() { |
| 479 @Override |
| 480 protected Properties initialValue() { |
| 481 return new Properties(); |
| 482 } |
| 483 }; |
| 484 |
| 485 @Override |
| 486 public StringBuffer format(CurrencyAmount currAmt, StringBuffer toAppendTo, Fi
eldPosition pos) { |
| 487 // TODO: This is ugly (although not as ugly as it was in ICU 58). |
| 488 // Currency should be a free parameter, not in property bag. Fix in ICU 60. |
| 489 Properties cprops = threadLocalCurrencyProperties.get(); |
| 490 synchronized (this) { |
| 491 cprops.copyFrom(properties); |
| 492 } |
| 493 cprops.setCurrency(currAmt.getCurrency()); |
| 494 FormatQuantity4 fq = new FormatQuantity4(currAmt.getNumber()); |
| 495 // TODO: Use a static format path here |
| 496 SingularFormat fmt = Endpoint.fromBTA(cprops, symbols); |
| 497 fmt.format(fq, toAppendTo, pos); |
| 498 fq.populateUFieldPosition(pos); |
| 499 return toAppendTo; |
168 } | 500 } |
169 | 501 |
170 /** @stable ICU 2.0 */ | 502 /** @stable ICU 2.0 */ |
171 @Override | 503 @Override |
172 public Number parse(String text, ParsePosition parsePosition) { | 504 public Number parse(String text, ParsePosition parsePosition) { |
173 // Backwards compatibility: use currency parse mode if this is a currency in
stance | 505 // Backwards compatibility: use currency parse mode if this is a currency in
stance |
174 Number result = Parse.parse(text, parsePosition, properties, symbols); | 506 Number result = Parse.parse(text, parsePosition, properties, symbols); |
175 // Backwards compatibility: return com.ibm.icu.math.BigDecimal | 507 // Backwards compatibility: return com.ibm.icu.math.BigDecimal |
176 if (result instanceof java.math.BigDecimal) { | 508 if (result instanceof java.math.BigDecimal) { |
177 result = new com.ibm.icu.math.BigDecimal((java.math.BigDecimal) result); | 509 result = new com.ibm.icu.math.BigDecimal((java.math.BigDecimal) result); |
178 } | 510 } |
179 return result; | 511 return result; |
180 } | |
181 | |
182 private static void populateUFieldPosition(FormatQuantity fq, FieldPosition fp
) { | |
183 if (fp instanceof UFieldPosition) { | |
184 ((UFieldPosition) fp).setFractionDigits((int)fq.getPluralOperand(Operand.v
), (long)fq.getPluralOperand(Operand.f)); | |
185 } | |
186 } | 512 } |
187 | 513 |
188 /** @stable ICU 49 */ | 514 /** @stable ICU 49 */ |
189 @Override | 515 @Override |
190 public CurrencyAmount parseCurrency(CharSequence text, ParsePosition parsePosi
tion) { | 516 public CurrencyAmount parseCurrency(CharSequence text, ParsePosition parsePosi
tion) { |
191 try { | 517 try { |
192 CurrencyAmount result = Parse.parseCurrency(text, parsePosition, propertie
s, symbols); | 518 CurrencyAmount result = Parse.parseCurrency(text, parsePosition, propertie
s, symbols); |
193 if (result == null) return null; | 519 if (result == null) return null; |
194 Number number = result.getNumber(); | 520 Number number = result.getNumber(); |
195 // Backwards compatibility: return com.ibm.icu.math.BigDecimal | 521 // Backwards compatibility: return com.ibm.icu.math.BigDecimal |
196 if (number instanceof java.math.BigDecimal) { | 522 if (number instanceof java.math.BigDecimal) { |
197 number = new com.ibm.icu.math.BigDecimal((java.math.BigDecimal) number); | 523 number = new com.ibm.icu.math.BigDecimal((java.math.BigDecimal) number); |
198 result = new CurrencyAmount(number, result.getCurrency()); | 524 result = new CurrencyAmount(number, result.getCurrency()); |
199 } | 525 } |
200 return result; | 526 return result; |
201 } catch (ParseException e) { | 527 } catch (ParseException e) { |
202 return null; | 528 return null; |
203 } | 529 } |
204 } | 530 } |
205 | 531 |
206 /** @stable ICU 3.6 */ | 532 //============================================================================
=========// |
207 @Override | 533 // GETTERS AND SETTERS
// |
208 public AttributedCharacterIterator formatToCharacterIterator(Object obj) { | 534 //============================================================================
=========// |
209 if (!(obj instanceof Number)) throw new IllegalArgumentException(); | 535 |
210 Number number = (Number) obj; | 536 /** |
211 return formatter.formatToCharacterIterator(FormatQuantitySelector.from(numbe
r)); | 537 * Returns a copy of the decimal format symbols used by this formatter. |
212 } | |
213 | |
214 /** | |
215 * Returns a copy of the decimal format symbols used by this format. | |
216 * | 538 * |
217 * @return desired DecimalFormatSymbols | 539 * @return desired DecimalFormatSymbols |
218 * @see DecimalFormatSymbols | 540 * @see DecimalFormatSymbols |
219 * @stable ICU 2.0 | 541 * @stable ICU 2.0 |
220 */ | 542 */ |
221 public synchronized DecimalFormatSymbols getDecimalFormatSymbols() { | 543 public synchronized DecimalFormatSymbols getDecimalFormatSymbols() { |
222 return (DecimalFormatSymbols) symbols.clone(); | 544 return (DecimalFormatSymbols) symbols.clone(); |
223 } | 545 } |
224 | 546 |
225 /** | 547 /** |
226 * Sets the decimal format symbols used by this format. The format uses a copy
of the provided | 548 * Sets the decimal format symbols used by this formatter. The formatter uses
a copy of the |
227 * symbols. | 549 * provided symbols. |
228 * | 550 * |
229 * @param newSymbols desired DecimalFormatSymbols | 551 * @param newSymbols desired DecimalFormatSymbols |
230 * @see DecimalFormatSymbols | 552 * @see DecimalFormatSymbols |
231 * @stable ICU 2.0 | 553 * @stable ICU 2.0 |
232 */ | 554 */ |
233 public synchronized void setDecimalFormatSymbols(DecimalFormatSymbols newSymbo
ls) { | 555 public synchronized void setDecimalFormatSymbols(DecimalFormatSymbols newSymbo
ls) { |
234 symbols = (DecimalFormatSymbols) newSymbols.clone(); | 556 symbols = (DecimalFormatSymbols) newSymbols.clone(); |
235 refreshFormatter(); | 557 refreshFormatter(); |
236 } | 558 } |
237 | 559 |
238 /** @stable ICU 2.0 */ | 560 /** |
| 561 * <strong>Affixes:</strong> Gets the positive prefix string currently being u
sed to format |
| 562 * numbers. |
| 563 * |
| 564 * <p>If the affix was specified via the pattern, the string returned by this
method will have |
| 565 * locale symbols substituted in place of special characters according to the
LDML specification. |
| 566 * If the affix was specified via {@link #setPositivePrefix}, the string will
be returned |
| 567 * literally. |
| 568 * |
| 569 * @return The string being prepended to positive numbers. |
| 570 * @category Affixes |
| 571 * @stable ICU 2.0 |
| 572 */ |
239 public synchronized String getPositivePrefix() { | 573 public synchronized String getPositivePrefix() { |
240 CharSequence result = properties.getPositivePrefix(); | 574 String result = exportedProperties.getPositivePrefix(); |
241 return (result == null) ? "" : result.toString(); | 575 return (result == null) ? "" : result; |
242 } | 576 } |
243 | 577 |
244 /** @stable ICU 2.0 */ | 578 /** |
245 public synchronized void setPositivePrefix(String newValue) { | 579 * <strong>Affixes:</strong> Sets the string to prepend to positive numbers. F
or example, if you |
246 properties.setPositivePrefix(newValue); | 580 * set the value "#", then the number 123 will be formatted as "#123" in the l
ocale |
247 refreshFormatter(); | 581 * <em>en-US</em>. |
248 } | 582 * |
249 | 583 * <p>Using this method overrides the affix specified via the pattern, and unl
ike the pattern, the |
250 /** @stable ICU 2.0 */ | 584 * string given to this method will be interpreted literally WITHOUT locale sy
mbol substitutions. |
| 585 * |
| 586 * @param prefix The literal string to prepend to positive numbers. |
| 587 * @category Affixes |
| 588 * @stable ICU 2.0 |
| 589 */ |
| 590 public synchronized void setPositivePrefix(String prefix) { |
| 591 properties.setPositivePrefix(prefix); |
| 592 refreshFormatter(); |
| 593 } |
| 594 |
| 595 /** |
| 596 * <strong>Affixes:</strong> Gets the negative prefix string currently being u
sed to format |
| 597 * numbers. |
| 598 * |
| 599 * <p>If the affix was specified via the pattern, the string returned by this
method will have |
| 600 * locale symbols substituted in place of special characters according to the
LDML specification. |
| 601 * If the affix was specified via {@link #setNegativePrefix}, the string will
be returned |
| 602 * literally. |
| 603 * |
| 604 * @return The string being prepended to negative numbers. |
| 605 * @category Affixes |
| 606 * @stable ICU 2.0 |
| 607 */ |
251 public synchronized String getNegativePrefix() { | 608 public synchronized String getNegativePrefix() { |
252 CharSequence result = properties.getNegativePrefix(); | 609 String result = exportedProperties.getNegativePrefix(); |
253 return (result == null) ? "" : result.toString(); | 610 return (result == null) ? "" : result; |
254 } | 611 } |
255 | 612 |
256 /** @stable ICU 2.0 */ | 613 /** |
257 public synchronized void setNegativePrefix(String newValue) { | 614 * <strong>Affixes:</strong> Sets the string to prepend to negative numbers. F
or example, if you |
258 properties.setNegativePrefix(newValue); | 615 * set the value "#", then the number -123 will be formatted as "#123" in the
locale |
259 refreshFormatter(); | 616 * <em>en-US</em> (overriding the implicit default '-' in the pattern). |
260 } | 617 * |
261 | 618 * <p>Using this method overrides the affix specified via the pattern, and unl
ike the pattern, the |
262 /** @stable ICU 2.0 */ | 619 * string given to this method will be interpreted literally WITHOUT locale sy
mbol substitutions. |
| 620 * |
| 621 * @param suffix The literal string to prepend to negative numbers. |
| 622 * @category Affixes |
| 623 * @stable ICU 2.0 |
| 624 */ |
| 625 public synchronized void setNegativePrefix(String suffix) { |
| 626 properties.setNegativePrefix(suffix); |
| 627 refreshFormatter(); |
| 628 } |
| 629 |
| 630 /** |
| 631 * <strong>Affixes:</strong> Gets the positive suffix string currently being u
sed to format |
| 632 * numbers. |
| 633 * |
| 634 * <p>If the affix was specified via the pattern, the string returned by this
method will have |
| 635 * locale symbols substituted in place of special characters according to the
LDML specification. |
| 636 * If the affix was specified via {@link #setPositiveSuffix}, the string will
be returned |
| 637 * literally. |
| 638 * |
| 639 * @return The string being appended to positive numbers. |
| 640 * @category Affixes |
| 641 * @stable ICU 2.0 |
| 642 */ |
263 public synchronized String getPositiveSuffix() { | 643 public synchronized String getPositiveSuffix() { |
264 CharSequence result = properties.getPositiveSuffix(); | 644 String result = exportedProperties.getPositiveSuffix(); |
265 return (result == null) ? "" : result.toString(); | 645 return (result == null) ? "" : result; |
266 } | 646 } |
267 | 647 |
268 /** @stable ICU 2.0 */ | 648 /** |
269 public synchronized void setPositiveSuffix(String newValue) { | 649 * <strong>Affixes:</strong> Sets the string to append to positive numbers. Fo
r example, if you |
270 properties.setPositiveSuffix(newValue); | 650 * set the value "#", then the number 123 will be formatted as "123#" in the l
ocale |
271 refreshFormatter(); | 651 * <em>en-US</em>. |
272 } | 652 * |
273 | 653 * <p>Using this method overrides the affix specified via the pattern, and unl
ike the pattern, the |
274 /** @stable ICU 2.0 */ | 654 * string given to this method will be interpreted literally WITHOUT locale sy
mbol substitutions. |
| 655 * |
| 656 * @param suffix The literal string to append to positive numbers. |
| 657 * @category Affixes |
| 658 * @stable ICU 2.0 |
| 659 */ |
| 660 public synchronized void setPositiveSuffix(String suffix) { |
| 661 properties.setPositiveSuffix(suffix); |
| 662 refreshFormatter(); |
| 663 } |
| 664 |
| 665 /** |
| 666 * <strong>Affixes:</strong> Gets the negative suffix string currently being u
sed to format |
| 667 * numbers. |
| 668 * |
| 669 * <p>If the affix was specified via the pattern, the string returned by this
method will have |
| 670 * locale symbols substituted in place of special characters according to the
LDML specification. |
| 671 * If the affix was specified via {@link #setNegativeSuffix}, the string will
be returned |
| 672 * literally. |
| 673 * |
| 674 * @return The string being appended to negative numbers. |
| 675 * @category Affixes |
| 676 * @stable ICU 2.0 |
| 677 */ |
275 public synchronized String getNegativeSuffix() { | 678 public synchronized String getNegativeSuffix() { |
276 CharSequence result = properties.getNegativeSuffix(); | 679 String result = exportedProperties.getNegativeSuffix(); |
277 return (result == null) ? "" : result.toString(); | 680 return (result == null) ? "" : result; |
278 } | 681 } |
279 | 682 |
280 /** @stable ICU 2.0 */ | 683 /** |
281 public synchronized void setNegativeSuffix(String newValue) { | 684 * <strong>Affixes:</strong> Sets the string to append to negative numbers. Fo
r example, if you |
282 properties.setNegativeSuffix(newValue); | 685 * set the value "#", then the number 123 will be formatted as "123#" in the l
ocale |
283 refreshFormatter(); | 686 * <em>en-US</em>. |
284 } | 687 * |
285 | 688 * <p>Using this method overrides the affix specified via the pattern, and unl
ike the pattern, the |
286 /** @stable ICU 2.0 */ | 689 * string given to this method will be interpreted literally WITHOUT locale sy
mbol substitutions. |
| 690 * |
| 691 * @param suffix The literal string to append to negative numbers. |
| 692 * @category Affixes |
| 693 * @stable ICU 2.0 |
| 694 */ |
| 695 public synchronized void setNegativeSuffix(String suffix) { |
| 696 properties.setNegativeSuffix(suffix); |
| 697 refreshFormatter(); |
| 698 } |
| 699 |
| 700 /** |
| 701 * @return The multiplier being applied to numbers before they are formatted. |
| 702 * @see #setMultiplier |
| 703 * @category Multipliers |
| 704 * @stable ICU 2.0 |
| 705 */ |
287 public synchronized int getMultiplier() { | 706 public synchronized int getMultiplier() { |
288 if (properties.getMultiplier() != null) { | 707 if (properties.getMultiplier() != null) { |
289 return properties.getMultiplier().intValue(); | 708 return properties.getMultiplier().intValue(); |
290 } else { | 709 } else { |
291 return (int) Math.pow(10, properties.getMagnitudeMultiplier()); | 710 return (int) Math.pow(10, properties.getMagnitudeMultiplier()); |
292 } | 711 } |
293 } | 712 } |
294 | 713 |
295 /** @stable ICU 2.0 */ | 714 /** |
296 public synchronized void setMultiplier(int newValue) { | 715 * Sets a number that will be used to multiply all numbers prior to formatting
. For example, when |
297 if (newValue == 0) { | 716 * formatting percents, a multiplier of 100 can be used. |
| 717 * |
| 718 * <p>If a percent or permille sign is specified in the pattern, the multiplie
r is automatically |
| 719 * set to 100 or 1000, respectively. |
| 720 * |
| 721 * <p>If the number specified here is a power of 10, a more efficient code pat
h will be used. |
| 722 * |
| 723 * @param multiplier The number by which all numbers passed to {@link #format}
will be multiplied. |
| 724 * @throws IllegalArgumentException If the given multiplier is zero. |
| 725 * @category Multipliers |
| 726 * @stable ICU 2.0 |
| 727 */ |
| 728 public synchronized void setMultiplier(int multiplier) { |
| 729 if (multiplier == 0) { |
298 throw new IllegalArgumentException("Multiplier must be nonzero."); | 730 throw new IllegalArgumentException("Multiplier must be nonzero."); |
299 } | 731 } |
300 | 732 |
301 // Try to convert to a magnitude multiplier first | 733 // Try to convert to a magnitude multiplier first |
302 int delta = 0; | 734 int delta = 0; |
303 int value = newValue; | 735 int value = multiplier; |
304 while (newValue != 1) { | 736 while (multiplier != 1) { |
305 delta++; | 737 delta++; |
306 int temp = value / 10; | 738 int temp = value / 10; |
307 if (temp * 10 != value) { | 739 if (temp * 10 != value) { |
308 delta = -1; | 740 delta = -1; |
309 break; | 741 break; |
310 } | 742 } |
311 value = temp; | 743 value = temp; |
312 } | 744 } |
313 if (delta != -1) { | 745 if (delta != -1) { |
314 properties.setMagnitudeMultiplier(delta); | 746 properties.setMagnitudeMultiplier(delta); |
315 } else { | 747 } else { |
316 properties.setMultiplier(java.math.BigDecimal.valueOf(newValue)); | 748 properties.setMultiplier(java.math.BigDecimal.valueOf(multiplier)); |
317 } | 749 } |
318 refreshFormatter(); | 750 refreshFormatter(); |
319 } | 751 } |
320 | 752 |
321 /** @stable ICU 2.0 */ | 753 /** |
| 754 * @return The increment to which numbers are being rounded. |
| 755 * @see #setRoundingIncrement |
| 756 * @category Rounding |
| 757 * @stable ICU 2.0 |
| 758 */ |
322 public synchronized java.math.BigDecimal getRoundingIncrement() { | 759 public synchronized java.math.BigDecimal getRoundingIncrement() { |
323 return properties.getRoundingInterval(); | 760 return exportedProperties.getRoundingIncrement(); |
324 } | 761 } |
325 | 762 |
326 /** @stable ICU 2.0 */ | 763 /** |
327 public synchronized void setRoundingIncrement(java.math.BigDecimal newValue) { | 764 * <strong>Rounding and Digit Limits:</strong> Sets an increment, or interval,
to which numbers |
| 765 * are rounded. For example, a rounding increment of 0.05 will cause the numbe
r 1.23 to be rounded |
| 766 * to 1.25 in the default rounding mode. |
| 767 * |
| 768 * <p>The rounding increment can be specified via the pattern string: for exam
ple, the pattern |
| 769 * "#,##0.05" encodes a rounding increment of 0.05. |
| 770 * |
| 771 * <p>The rounding increment is applied <em>after</em> any multipliers might t
ake effect; for |
| 772 * example, in scientific notation or when {@link #setMultiplier} is used. |
| 773 * |
| 774 * <p>See {@link #setMaximumFractionDigits} and {@link #setMaximumSignificantD
igits} for two other |
| 775 * ways of specifying rounding strategies. |
| 776 * |
| 777 * @param increment The increment to which numbers are to be rounded. |
| 778 * @see #setRoundingMode |
| 779 * @see #setMaximumFractionDigits |
| 780 * @see #setMaximumSignificantDigits |
| 781 * @category Rounding |
| 782 * @stable ICU 2.0 |
| 783 */ |
| 784 public synchronized void setRoundingIncrement(java.math.BigDecimal increment)
{ |
328 // Backwards compatibility: ignore rounding increment if zero, | 785 // Backwards compatibility: ignore rounding increment if zero, |
329 // and instead set maximum fraction digits. | 786 // and instead set maximum fraction digits. |
330 if (newValue.compareTo(java.math.BigDecimal.ZERO) == 0) { | 787 if (increment != null && increment.compareTo(java.math.BigDecimal.ZERO) == 0
) { |
331 properties.setMaximumFractionDigits(Integer.MAX_VALUE); | 788 properties.setMaximumFractionDigits(Integer.MAX_VALUE); |
332 return; | 789 return; |
333 } | 790 } |
334 | 791 |
335 properties.setRoundingInterval(newValue); | 792 properties.setRoundingIncrement(increment); |
336 refreshFormatter(); | 793 refreshFormatter(); |
337 } | 794 } |
338 | 795 |
339 /** @stable ICU 3.6 */ | 796 /** |
340 public synchronized void setRoundingIncrement(BigDecimal newValue) { | 797 * <strong>Rounding and Digit Limits:</strong> Overload of {@link |
341 java.math.BigDecimal javaBigDecimal = newValue.toBigDecimal(); | 798 * #setRoundingIncrement(java.math.BigDecimal)}. |
| 799 * |
| 800 * @param increment The increment to which numbers are to be rounded. |
| 801 * @see #setRoundingIncrement |
| 802 * @category Rounding |
| 803 * @stable ICU 3.6 |
| 804 */ |
| 805 public synchronized void setRoundingIncrement(BigDecimal increment) { |
| 806 java.math.BigDecimal javaBigDecimal = (increment == null) ? null : increment
.toBigDecimal(); |
342 setRoundingIncrement(javaBigDecimal); | 807 setRoundingIncrement(javaBigDecimal); |
343 } | 808 } |
344 | 809 |
345 /** @stable ICU 2.0 */ | 810 /** |
346 public synchronized void setRoundingIncrement(double newValue) { | 811 * <strong>Rounding and Digit Limits:</strong> Overload of {@link |
347 java.math.BigDecimal javaBigDecimal = java.math.BigDecimal.valueOf(newValue)
; | 812 * #setRoundingIncrement(java.math.BigDecimal)}. |
348 setRoundingIncrement(javaBigDecimal); | 813 * |
349 } | 814 * @param increment The increment to which numbers are to be rounded. |
350 | 815 * @see #setRoundingIncrement |
351 /** @stable ICU 2.0 */ | 816 * @category Rounding |
| 817 * @stable ICU 2.0 |
| 818 */ |
| 819 public synchronized void setRoundingIncrement(double increment) { |
| 820 if (increment == 0) { |
| 821 setRoundingIncrement((java.math.BigDecimal) null); |
| 822 } else { |
| 823 java.math.BigDecimal javaBigDecimal = java.math.BigDecimal.valueOf(increme
nt); |
| 824 setRoundingIncrement(javaBigDecimal); |
| 825 } |
| 826 } |
| 827 |
| 828 /** |
| 829 * @return The rounding mode being used to round numbers. |
| 830 * @see #setRoundingMode |
| 831 * @category Rounding |
| 832 * @stable ICU 2.0 |
| 833 */ |
352 @Override | 834 @Override |
353 public synchronized int getRoundingMode() { | 835 public synchronized int getRoundingMode() { |
354 RoundingMode mode = properties.getRoundingMode(); | 836 RoundingMode mode = exportedProperties.getRoundingMode(); |
355 return (mode == null) ? 0 : mode.ordinal(); | 837 return (mode == null) ? 0 : mode.ordinal(); |
356 } | 838 } |
357 | 839 |
358 /** @stable ICU 2.0 */ | 840 /** |
| 841 * <strong>Rounding and Digit Limits:</strong> Sets the {@link RoundingMode} u
sed to round |
| 842 * numbers. The default rounding mode is HALF_EVEN, which rounds decimals to t
heir closest whole |
| 843 * number, and rounds to the closest even number if at the midpoint. |
| 844 * |
| 845 * <p>For more detail on rounding modes, see <a |
| 846 * href="http://userguide.icu-project.org/formatparse/numbers/rounding-modes"
>the ICU User |
| 847 * Guide</a>. |
| 848 * |
| 849 * <p>For backwards compatibility, the rounding mode is specified as an int ar
gument, which can be |
| 850 * from either the constants in {@link BigDecimal} or the ordinal value of {@l
ink RoundingMode}. |
| 851 * The following two calls are functionally equivalent. |
| 852 * |
| 853 * <pre> |
| 854 * df.setRoundingMode(BigDecimal.ROUND_CEILING); |
| 855 * df.setRoundingMode(RoundingMode.CEILING.ordinal()); |
| 856 * </pre> |
| 857 * |
| 858 * @param roundingMode The integer constant rounding mode to use when formatti
ng numbers. |
| 859 * @category Rounding |
| 860 * @stable ICU 2.0 |
| 861 */ |
359 @Override | 862 @Override |
360 public synchronized void setRoundingMode(int roundingMode) { | 863 public synchronized void setRoundingMode(int roundingMode) { |
361 properties.setRoundingMode(RoundingMode.valueOf(roundingMode)); | 864 properties.setRoundingMode(RoundingMode.valueOf(roundingMode)); |
362 refreshFormatter(); | 865 refreshFormatter(); |
363 } | 866 } |
364 | 867 |
365 /** @stable ICU 2.0 */ | 868 /** |
366 public synchronized int getFormatWidth() { | 869 * @return The {@link java.math.MathContext} being used to round numbers. |
367 return properties.getPaddingWidth(); | 870 * @see #setMathContext |
368 } | 871 * @category Rounding |
369 | 872 * @stable ICU 4.2 |
370 /** @stable ICU 2.0 */ | 873 */ |
371 public synchronized void setFormatWidth(int width) { | 874 public synchronized java.math.MathContext getMathContext() { |
372 properties.setPaddingWidth(width); | 875 java.math.MathContext mathContext = exportedProperties.getMathContext(); |
373 refreshFormatter(); | 876 assert mathContext != null; |
374 } | 877 return mathContext; |
375 | 878 } |
376 /** @stable ICU 2.0 */ | 879 |
377 public synchronized char getPadCharacter() { | 880 /** |
378 CharSequence paddingString = properties.getPaddingString(); | 881 * <strong>Rounding and Digit Limits:</strong> Sets the {@link java.math.MathC
ontext} used to |
379 if (paddingString == null) { | 882 * round numbers. A "math context" encodes both a rounding mode and a number o
f significant |
380 return '.'; // TODO: Is this the correct behavior? | 883 * digits. |
381 } else { | 884 * |
382 return paddingString.charAt(0); | 885 * <p>This method is provided for users who require their output to conform to
a standard math |
383 } | 886 * context. <strong>Most users should call {@link #setRoundingMode} and/or {@l
ink |
384 } | 887 * #setMaximumSignificantDigits} instead of this method.</strong> |
385 | 888 * |
386 /** @stable ICU 2.0 */ | 889 * @param mathContext The MathContext to use when rounding numbers. |
387 public synchronized void setPadCharacter(char padChar) { | 890 * @see java.math.MathContext |
388 properties.setPaddingString(Character.toString(padChar)); | 891 * @category Rounding |
389 refreshFormatter(); | 892 * @stable ICU 4.2 |
390 } | 893 */ |
391 | 894 public synchronized void setMathContext(java.math.MathContext mathContext) { |
392 /** @stable ICU 2.0 */ | 895 properties.setMathContext(mathContext); |
393 public synchronized int getPadPosition() { | 896 refreshFormatter(); |
394 PaddingLocation loc = properties.getPaddingLocation(); | 897 } |
395 return (loc == null) ? PAD_BEFORE_PREFIX : loc.toOld(); | 898 |
396 } | 899 // Remember the ICU math context form in order to be able to return it from th
e API. |
397 | 900 // NOTE: This value is not serialized. (should it be?) |
398 /** @stable ICU 2.0 */ | 901 private transient int icuMathContextForm = MathContext.PLAIN; |
399 public synchronized void setPadPosition(int padPos) { | 902 |
400 properties.setPaddingLocation(PaddingLocation.fromOld(padPos)); | 903 /** |
401 refreshFormatter(); | 904 * @return The {@link com.ibm.icu.math.MathContext} being used to round number
s. |
402 } | 905 * @see #setMathContext |
403 | 906 * @category Rounding |
404 /** @stable ICU 2.0 */ | 907 * @stable ICU 4.2 |
405 public synchronized boolean isScientificNotation() { | 908 */ |
406 return ScientificFormat.useScientificNotation(properties); | |
407 } | |
408 | |
409 /** @stable ICU 2.0 */ | |
410 public synchronized void setScientificNotation(boolean useScientific) { | |
411 if (useScientific) { | |
412 properties.setExponentDigits(1); | |
413 } else { | |
414 properties.setExponentDigits(Properties.DEFAULT_EXPONENT_DIGITS); | |
415 } | |
416 refreshFormatter(); | |
417 } | |
418 | |
419 /** @stable ICU 2.0 */ | |
420 public synchronized byte getMinimumExponentDigits() { | |
421 return (byte) properties.getExponentDigits(); | |
422 } | |
423 | |
424 /** @stable ICU 2.0 */ | |
425 public synchronized void setMinimumExponentDigits(byte minExpDig) { | |
426 properties.setExponentDigits(minExpDig); | |
427 refreshFormatter(); | |
428 } | |
429 | |
430 /** @stable ICU 2.0 */ | |
431 public synchronized boolean isExponentSignAlwaysShown() { | |
432 return properties.getExponentShowPlusSign(); | |
433 } | |
434 | |
435 /** @stable ICU 2.0 */ | |
436 public synchronized void setExponentSignAlwaysShown(boolean expSignAlways) { | |
437 properties.setExponentShowPlusSign(expSignAlways); | |
438 refreshFormatter(); | |
439 } | |
440 | |
441 /** @stable ICU 2.0 */ | |
442 public synchronized int getGroupingSize() { | |
443 return properties.getGroupingSize(); | |
444 } | |
445 | |
446 /** @stable ICU 2.0 */ | |
447 public synchronized void setGroupingSize(int newValue) { | |
448 properties.setGroupingSize(newValue); | |
449 refreshFormatter(); | |
450 } | |
451 | |
452 /** @stable ICU 2.0 */ | |
453 public synchronized int getSecondaryGroupingSize() { | |
454 return properties.getSecondaryGroupingSize(); | |
455 } | |
456 | |
457 /** @stable ICU 2.0 */ | |
458 public synchronized void setSecondaryGroupingSize(int newValue) { | |
459 properties.setSecondaryGroupingSize(newValue); | |
460 refreshFormatter(); | |
461 } | |
462 | |
463 /** @stable ICU 2.0 */ | |
464 @Override | |
465 public synchronized boolean isGroupingUsed() { | |
466 return PositiveDecimalFormat.useGrouping(properties); | |
467 } | |
468 | |
469 /** @stable ICU 2.0 */ | |
470 @Override | |
471 public synchronized void setGroupingUsed(boolean newValue) { | |
472 if (newValue) { | |
473 // TODO(sffc): how should this be handled? | |
474 properties.setGroupingSize(3); | |
475 } else { | |
476 properties.setGroupingSize(Properties.DEFAULT_SECONDARY_GROUPING_SIZE); | |
477 } | |
478 refreshFormatter(); | |
479 } | |
480 | |
481 /** Remember the ICU math context form in order to be able to return it from t
he API. */ | |
482 private int icuMathContextForm = MathContext.PLAIN; | |
483 | |
484 /** @stable ICU 4.2 */ | |
485 public synchronized MathContext getMathContextICU() { | 909 public synchronized MathContext getMathContextICU() { |
486 java.math.MathContext mathContext = getMathContext(); | 910 java.math.MathContext mathContext = getMathContext(); |
487 return new MathContext( | 911 return new MathContext( |
488 mathContext.getPrecision(), | 912 mathContext.getPrecision(), |
489 icuMathContextForm, | 913 icuMathContextForm, |
490 false, | 914 false, |
491 mathContext.getRoundingMode().ordinal()); | 915 mathContext.getRoundingMode().ordinal()); |
492 } | 916 } |
493 | 917 |
494 /** @stable ICU 4.2 */ | 918 /** |
495 public synchronized void setMathContextICU(MathContext newValue) { | 919 * <strong>Rounding and Digit Limits:</strong> Overload of {@link #setMathCont
ext} for {@link |
496 icuMathContextForm = newValue.getForm(); | 920 * com.ibm.icu.math.MathContext}. |
| 921 * |
| 922 * @param mathContextICU The MathContext to use when rounding numbers. |
| 923 * @see #setMathContext(java.math.MathContext) |
| 924 * @category Rounding |
| 925 * @stable ICU 4.2 |
| 926 */ |
| 927 public synchronized void setMathContextICU(MathContext mathContextICU) { |
| 928 icuMathContextForm = mathContextICU.getForm(); |
497 java.math.MathContext mathContext; | 929 java.math.MathContext mathContext; |
498 if (newValue.getLostDigits()) { | 930 if (mathContextICU.getLostDigits()) { |
499 // The getLostDigits() feature in ICU MathContext means "throw an Arithmet
icException if | 931 // The getLostDigits() feature in ICU MathContext means "throw an Arithmet
icException if |
500 // rounding causes digits to be lost". That feature is called RoundingMode
.UNNECESSARY in | 932 // rounding causes digits to be lost". That feature is called RoundingMode
.UNNECESSARY in |
501 // Java MathContext. | 933 // Java MathContext. |
502 mathContext = new java.math.MathContext( | 934 mathContext = new java.math.MathContext(mathContextICU.getDigits(), Roundi
ngMode.UNNECESSARY); |
503 newValue.getDigits(), | |
504 RoundingMode.UNNECESSARY); | |
505 } else { | 935 } else { |
506 mathContext = new java.math.MathContext( | 936 mathContext = |
507 newValue.getDigits(), | 937 new java.math.MathContext( |
508 RoundingMode.valueOf(newValue.getRoundingMode())); | 938 mathContextICU.getDigits(), RoundingMode.valueOf(mathContextICU.ge
tRoundingMode())); |
509 } | 939 } |
510 setMathContext(mathContext); | 940 setMathContext(mathContext); |
511 } | 941 } |
512 | 942 |
513 /** @stable ICU 4.2 */ | 943 /** |
514 public synchronized java.math.MathContext getMathContext() { | 944 * @return The effective minimum number of digits before the decimal separator
. |
515 java.math.MathContext mathContext = properties.getMathContext(); | 945 * @see #setMinimumIntegerDigits |
516 if (mathContext == null) { | 946 * @category Rounding |
517 return new java.math.MathContext(0, RoundingMode.HALF_EVEN); | 947 * @stable ICU 2.0 |
518 } else { | 948 */ |
519 return mathContext; | 949 @Override |
520 } | 950 public synchronized int getMinimumIntegerDigits() { |
521 } | 951 return exportedProperties.getMinimumIntegerDigits(); |
522 | 952 } |
523 /** @stable ICU 4.2 */ | 953 |
524 public synchronized void setMathContext(java.math.MathContext newValue) { | 954 /** |
525 properties.setMathContext(newValue); | 955 * <strong>Rounding and Digit Limits:</strong> Sets the minimum number of digi
ts to display before |
526 refreshFormatter(); | 956 * the decimal separator. If the number has fewer than this many digits, the n
umber is padded with |
527 } | 957 * zeros. |
528 | 958 * |
529 /** @stable ICU 54 */ | 959 * <p>For example, if minimum integer digits is 3, the number 12.3 will be pri
nted as "001.23". |
530 public synchronized void setDecimalPatternMatchRequired(boolean value) { | 960 * |
531 properties.setDecimalPatternMatchRequired(value); | 961 * <p>Minimum integer and minimum and maximum fraction digits can be specified
via the pattern |
532 refreshFormatter(); | 962 * string. For example, "#,#00.00#" has 2 minimum integer digits, 2 minimum fr
action digits, and 3 |
533 } | 963 * maximum fraction digits. Note that it is not possible to specify maximium i
nteger digits in the |
534 | 964 * pattern except in scientific notation. |
535 /** @stable ICU 54 */ | 965 * |
536 public synchronized boolean isDecimalPatternMatchRequired() { | 966 * @param value The minimum number of digits before the decimal separator. |
537 return properties.getDecimalPatternMatchRequired(); | 967 * @category Rounding |
538 } | 968 * @stable ICU 2.0 |
539 | 969 */ |
540 /** @stable ICU 2.0 */ | 970 @Override |
541 public synchronized boolean isDecimalSeparatorAlwaysShown() { | 971 public synchronized void setMinimumIntegerDigits(int value) { |
542 return properties.getAlwaysShowDecimal(); | 972 properties.setMinimumIntegerDigits(value); |
543 } | 973 refreshFormatter(); |
544 | 974 } |
545 /** @stable ICU 2.0 */ | 975 |
546 public synchronized void setDecimalSeparatorAlwaysShown(boolean newValue) { | 976 /** |
547 properties.setAlwaysShowDecimal(newValue); | 977 * @return The effective maximum number of digits before the decimal separator
. |
548 refreshFormatter(); | 978 * @see #setMaximumIntegerDigits |
549 } | 979 * @category Rounding |
550 | 980 * @stable ICU 2.0 |
551 /** @stable ICU 2.0 */ | 981 */ |
552 @Override | 982 @Override |
553 public synchronized int getMaximumIntegerDigits() { | 983 public synchronized int getMaximumIntegerDigits() { |
554 return properties.getMaximumIntegerDigits(); | 984 return exportedProperties.getMaximumIntegerDigits(); |
555 } | 985 } |
556 | 986 |
557 /** @stable ICU 2.0 */ | 987 /** |
558 @Override | 988 * <strong>Rounding and Digit Limits:</strong> Sets the maximum number of digi
ts to display before |
559 public synchronized int getMinimumIntegerDigits() { | 989 * the decimal separator. If the number has more than this many digits, the nu
mber is truncated. |
560 return properties.getMinimumIntegerDigits(); | 990 * |
561 } | 991 * <p>For example, if maximum integer digits is 3, the number 12345 will be pr
inted as "345". |
562 | 992 * |
563 /** @stable ICU 2.0 */ | 993 * <p>Minimum integer and minimum and maximum fraction digits can be specified
via the pattern |
564 @Override | 994 * string. For example, "#,#00.00#" has 2 minimum integer digits, 2 minimum fr
action digits, and 3 |
565 public synchronized void setMaximumIntegerDigits(int newValue) { | 995 * maximum fraction digits. Note that it is not possible to specify maximium i
nteger digits in the |
566 properties.setMaximumIntegerDigits(newValue); | 996 * pattern except in scientific notation. |
567 refreshFormatter(); | 997 * |
568 } | 998 * @param value The maximum number of digits before the decimal separator. |
569 | 999 * @category Rounding |
570 /** @stable ICU 2.0 */ | 1000 * @stable ICU 2.0 |
571 @Override | 1001 */ |
572 public synchronized void setMinimumIntegerDigits(int newValue) { | 1002 @Override |
573 properties.setMinimumIntegerDigits(newValue); | 1003 public synchronized void setMaximumIntegerDigits(int value) { |
574 refreshFormatter(); | 1004 properties.setMaximumIntegerDigits(value); |
575 } | 1005 refreshFormatter(); |
576 | 1006 } |
577 /** @stable ICU 2.0 */ | 1007 |
| 1008 /** |
| 1009 * @return The effective minimum number of integer digits after the decimal se
parator. |
| 1010 * @see #setMaximumIntegerDigits |
| 1011 * @category Rounding |
| 1012 * @stable ICU 2.0 |
| 1013 */ |
| 1014 @Override |
| 1015 public synchronized int getMinimumFractionDigits() { |
| 1016 return exportedProperties.getMinimumFractionDigits(); |
| 1017 } |
| 1018 |
| 1019 /** |
| 1020 * <strong>Rounding and Digit Limits:</strong> Sets the minimum number of digi
ts to display after |
| 1021 * the decimal separator. If the number has fewer than this many digits, the n
umber is padded with |
| 1022 * zeros. |
| 1023 * |
| 1024 * <p>For example, if minimum fraction digits is 2, the number 123.4 will be p
rinted as "123.40". |
| 1025 * |
| 1026 * <p>Minimum integer and minimum and maximum fraction digits can be specified
via the pattern |
| 1027 * string. For example, "#,#00.00#" has 2 minimum integer digits, 2 minimum fr
action digits, and 3 |
| 1028 * maximum fraction digits. Note that it is not possible to specify maximium i
nteger digits in the |
| 1029 * pattern except in scientific notation. |
| 1030 * |
| 1031 * <p>See {@link #setRoundingIncrement} and {@link #setMaximumSignificantDigit
s} for two other |
| 1032 * ways of specifying rounding strategies. |
| 1033 * |
| 1034 * @param value The minimum number of integer digits after the decimal separat
or. |
| 1035 * @see #setRoundingMode |
| 1036 * @see #setRoundingIncrement |
| 1037 * @see #setMaximumSignificantDigits |
| 1038 * @category Rounding |
| 1039 * @stable ICU 2.0 |
| 1040 */ |
| 1041 @Override |
| 1042 public synchronized void setMinimumFractionDigits(int value) { |
| 1043 properties.setMinimumFractionDigits(value); |
| 1044 refreshFormatter(); |
| 1045 } |
| 1046 |
| 1047 /** |
| 1048 * @return The effective maximum number of integer digits after the decimal se
parator. |
| 1049 * @see #setMaximumIntegerDigits |
| 1050 * @category Rounding |
| 1051 * @stable ICU 2.0 |
| 1052 */ |
578 @Override | 1053 @Override |
579 public synchronized int getMaximumFractionDigits() { | 1054 public synchronized int getMaximumFractionDigits() { |
580 return properties.getMaximumFractionDigits(); | 1055 return exportedProperties.getMaximumFractionDigits(); |
581 } | 1056 } |
582 | 1057 |
583 /** @stable ICU 2.0 */ | 1058 /** |
584 @Override | 1059 * <strong>Rounding and Digit Limits:</strong> Sets the maximum number of digi
ts to display after |
585 public synchronized int getMinimumFractionDigits() { | 1060 * the decimal separator. If the number has more than this many digits, the nu
mber is rounded |
586 return properties.getMinimumFractionDigits(); | 1061 * according to the rounding mode. |
587 } | 1062 * |
588 | 1063 * <p>For example, if maximum fraction digits is 2, the number 123.456 will be
printed as |
589 /** @stable ICU 2.0 */ | 1064 * "123.46". |
590 @Override | 1065 * |
591 public synchronized void setMaximumFractionDigits(int newValue) { | 1066 * <p>Minimum integer and minimum and maximum fraction digits can be specified
via the pattern |
592 properties.setMaximumFractionDigits(newValue); | 1067 * string. For example, "#,#00.00#" has 2 minimum integer digits, 2 minimum fr
action digits, and 3 |
593 refreshFormatter(); | 1068 * maximum fraction digits. Note that it is not possible to specify maximium i
nteger digits in the |
594 } | 1069 * pattern except in scientific notation. |
595 | 1070 * |
596 /** @stable ICU 2.0 */ | 1071 * @param value The maximum number of integer digits after the decimal separat
or. |
597 @Override | 1072 * @see #setRoundingMode |
598 public synchronized void setMinimumFractionDigits(int newValue) { | 1073 * @category Rounding |
599 properties.setMinimumFractionDigits(newValue); | 1074 * @stable ICU 2.0 |
600 refreshFormatter(); | 1075 */ |
601 } | 1076 @Override |
602 | 1077 public synchronized void setMaximumFractionDigits(int value) { |
603 /** @stable ICU 3.0 */ | 1078 properties.setMaximumFractionDigits(value); |
604 public synchronized int getMinimumSignificantDigits() { | 1079 refreshFormatter(); |
605 return properties.getMinimumSignificantDigits(); | 1080 } |
606 } | 1081 |
607 | 1082 /** |
608 /** @stable ICU 3.0 */ | 1083 * @return Whether significant digits are being used in rounding. |
609 public synchronized int getMaximumSignificantDigits() { | 1084 * @see #setSignificantDigitsUsed |
610 return properties.getMaximumSignificantDigits(); | 1085 * @category Rounding |
611 } | 1086 * @stable ICU 3.0 |
612 | 1087 */ |
613 /** @stable ICU 3.0 */ | |
614 public synchronized void setMinimumSignificantDigits(int min) { | |
615 properties.setMinimumSignificantDigits(min); | |
616 refreshFormatter(); | |
617 } | |
618 | |
619 /** @stable ICU 3.0 */ | |
620 public synchronized void setMaximumSignificantDigits(int max) { | |
621 properties.setMaximumSignificantDigits(max); | |
622 refreshFormatter(); | |
623 } | |
624 | |
625 /** @stable ICU 3.0 */ | |
626 public synchronized boolean areSignificantDigitsUsed() { | 1088 public synchronized boolean areSignificantDigitsUsed() { |
627 return SignificantDigitsRounder.useSignificantDigits(properties); | 1089 return SignificantDigitsRounder.useSignificantDigits(properties); |
628 } | 1090 } |
629 | 1091 |
630 /** @stable ICU 3.0 */ | 1092 /** |
| 1093 * <strong>Rounding and Digit Limits:</strong> Sets whether significant digits
are to be used in |
| 1094 * rounding. |
| 1095 * |
| 1096 * <p>Calling <code>df.setSignificantDigitsUsed(true)</code> is functionally e
quivalent to: |
| 1097 * |
| 1098 * <pre> |
| 1099 * df.setMinimumSignificantDigits(1); |
| 1100 * df.setMaximumSignificantDigits(6); |
| 1101 * </pre> |
| 1102 * |
| 1103 * @param useSignificantDigits true to enable significant digit rounding; fals
e to disable it. |
| 1104 * @category Rounding |
| 1105 * @stable ICU 3.0 |
| 1106 */ |
631 public synchronized void setSignificantDigitsUsed(boolean useSignificantDigits
) { | 1107 public synchronized void setSignificantDigitsUsed(boolean useSignificantDigits
) { |
632 if (useSignificantDigits) { | 1108 if (useSignificantDigits) { |
633 // These are the default values from the old implementation. | 1109 // These are the default values from the old implementation. |
634 properties.setMinimumSignificantDigits(1); | 1110 properties.setMinimumSignificantDigits(1); |
635 properties.setMaximumSignificantDigits(6); | 1111 properties.setMaximumSignificantDigits(6); |
636 } else { | 1112 } else { |
637 properties.setMinimumSignificantDigits(Properties.DEFAULT_MINIMUM_SIGNIFIC
ANT_DIGITS); | 1113 properties.setMinimumSignificantDigits(Properties.DEFAULT_MINIMUM_SIGNIFIC
ANT_DIGITS); |
638 properties.setMaximumSignificantDigits(Properties.DEFAULT_MAXIMUM_SIGNIFIC
ANT_DIGITS); | 1114 properties.setMaximumSignificantDigits(Properties.DEFAULT_MAXIMUM_SIGNIFIC
ANT_DIGITS); |
| 1115 properties.setSignificantDigitsMode(null); |
639 } | 1116 } |
640 refreshFormatter(); | 1117 refreshFormatter(); |
641 } | 1118 } |
642 | 1119 |
643 /** @stable ICU 2.2 */ | 1120 /** |
644 @Override | 1121 * @return The effective minimum number of significant digits displayed. |
645 public synchronized void setCurrency(Currency theCurrency) { | 1122 * @see #setMinimumSignificantDigits |
646 properties.setCurrency(theCurrency); | 1123 * @category Rounding |
| 1124 * @stable ICU 3.0 |
| 1125 */ |
| 1126 public synchronized int getMinimumSignificantDigits() { |
| 1127 return exportedProperties.getMinimumSignificantDigits(); |
| 1128 } |
| 1129 |
| 1130 /** |
| 1131 * <strong>Rounding and Digit Limits:</strong> Sets the minimum number of sign
ificant digits to be |
| 1132 * displayed. If the number of significant digits is less than this value, the
number will be |
| 1133 * padded with zeros as necessary. |
| 1134 * |
| 1135 * <p>For example, if minimum significant digits is 3 and the number is 1.2, t
he number will be |
| 1136 * printed as "1.20". |
| 1137 * |
| 1138 * @param value The minimum number of significant digits to display. |
| 1139 * @see #setSignificantDigitsMode |
| 1140 * @category Rounding |
| 1141 * @stable ICU 3.0 |
| 1142 */ |
| 1143 public synchronized void setMinimumSignificantDigits(int value) { |
| 1144 properties.setMinimumSignificantDigits(value); |
| 1145 refreshFormatter(); |
| 1146 } |
| 1147 |
| 1148 /** |
| 1149 * @return The effective maximum number of significant digits displayed. |
| 1150 * @see #setMaximumSignificantDigits |
| 1151 * @category Rounding |
| 1152 * @stable ICU 3.0 |
| 1153 */ |
| 1154 public synchronized int getMaximumSignificantDigits() { |
| 1155 return exportedProperties.getMaximumSignificantDigits(); |
| 1156 } |
| 1157 |
| 1158 /** |
| 1159 * <strong>Rounding and Digit Limits:</strong> Sets the maximum number of sign
ificant digits to be |
| 1160 * displayed. If the number of significant digits in the number exceeds this v
alue, the number |
| 1161 * will be rounded according to the current rounding mode. |
| 1162 * |
| 1163 * <p>For example, if maximum significant digits is 3 and the number is 12345,
the number will be |
| 1164 * printed as "12300". |
| 1165 * |
| 1166 * <p>See {@link #setRoundingIncrement} and {@link #setMaximumFractionDigits}
for two other ways |
| 1167 * of specifying rounding strategies. |
| 1168 * |
| 1169 * @param value The maximum number of significant digits to display. |
| 1170 * @see #setRoundingMode |
| 1171 * @see #setRoundingIncrement |
| 1172 * @see #setMaximumFractionDigits |
| 1173 * @see #setSignificantDigitsMode |
| 1174 * @category Rounding |
| 1175 * @stable ICU 3.0 |
| 1176 */ |
| 1177 public synchronized void setMaximumSignificantDigits(int value) { |
| 1178 properties.setMaximumSignificantDigits(value); |
| 1179 refreshFormatter(); |
| 1180 } |
| 1181 |
| 1182 /** |
| 1183 * @return The current significant digits mode. |
| 1184 * @see #setSignificantDigitsMode |
| 1185 * @category Rounding |
| 1186 * @internal |
| 1187 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1188 */ |
| 1189 @Deprecated |
| 1190 public synchronized SignificantDigitsMode getSignificantDigitsMode() { |
| 1191 return exportedProperties.getSignificantDigitsMode(); |
| 1192 } |
| 1193 |
| 1194 /** |
| 1195 * <strong>Rounding and Digit Limits:</strong> Sets the strategy used for reso
lving |
| 1196 * minimum/maximum significant digits when minimum/maximum integer and/or frac
tion digits are |
| 1197 * specified. There are three modes: |
| 1198 * |
| 1199 * <ul> |
| 1200 * <li>Mode A: OVERRIDE_MAXIMUM_FRACTION. This is the default. Settings in m
aximum fraction are |
| 1201 * ignored. |
| 1202 * <li>Mode B: RESPECT_MAXIMUM_FRACTION. Round to maximum fraction even if d
oing so will prevent |
| 1203 * minimum significant from being respected. |
| 1204 * <li>Mode C: ENSURE_MINIMUM_SIGNIFICANT. Respect maximum fraction, but alw
ays ensure that |
| 1205 * minimum significant digits are shown. |
| 1206 * </ul> |
| 1207 * |
| 1208 * <p>The following table illustrates the difference. Below, minFrac=1, maxFra
c=2, minSig=3, and |
| 1209 * maxSig=4: |
| 1210 * |
| 1211 * <pre> |
| 1212 * Mode A | Mode B | Mode C |
| 1213 * ---------+----------+---------- |
| 1214 * 12340.0 | 12340.0 | 12340.0 |
| 1215 * 1234.0 | 1234.0 | 1234.0 |
| 1216 * 123.4 | 123.4 | 123.4 |
| 1217 * 12.34 | 12.34 | 12.34 |
| 1218 * 1.234 | 1.23 | 1.23 |
| 1219 * 0.1234 | 0.12 | 0.123 |
| 1220 * 0.01234 | 0.01 | 0.0123 |
| 1221 * 0.001234 | 0.00 | 0.00123 |
| 1222 * </pre> |
| 1223 * |
| 1224 * @param mode The significant digits mode to use. |
| 1225 * @category Rounding |
| 1226 * @internal |
| 1227 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1228 */ |
| 1229 @Deprecated |
| 1230 public synchronized void setSignificantDigitsMode(SignificantDigitsMode mode)
{ |
| 1231 properties.setSignificantDigitsMode(mode); |
| 1232 refreshFormatter(); |
| 1233 } |
| 1234 |
| 1235 /** |
| 1236 * @return The minimum number of characters in formatted output. |
| 1237 * @see #setFormatWidth |
| 1238 * @category Padding |
| 1239 * @stable ICU 2.0 |
| 1240 */ |
| 1241 public synchronized int getFormatWidth() { |
| 1242 return exportedProperties.getFormatWidth(); |
| 1243 } |
| 1244 |
| 1245 /** |
| 1246 * <strong>Padding:</strong> Sets the minimum width of the string output by th
e formatting |
| 1247 * pipeline. For example, if padding is enabled and paddingWidth is set to 6,
formatting the |
| 1248 * number "3.14159" with the pattern "0.00" will result in "··3.14" if '·' is
your padding string. |
| 1249 * |
| 1250 * <p>If the number is longer than your padding width, the number will display
as if no padding |
| 1251 * width had been specified, which may result in strings longer than the paddi
ng width. |
| 1252 * |
| 1253 * <p>Padding can be specified in the pattern string using the '*' symbol. For
example, the format |
| 1254 * "*x######0" has a format width of 7 and a pad character of 'x'. |
| 1255 * |
| 1256 * <p>Padding is currently counted in UTF-16 code units; see <a |
| 1257 * href="http://bugs.icu-project.org/trac/ticket/13034">ticket #13034</a> for
more information. |
| 1258 * |
| 1259 * @param width The minimum number of characters in the output. |
| 1260 * @see #setPadCharacter |
| 1261 * @see #setPadPosition |
| 1262 * @category Padding |
| 1263 * @stable ICU 2.0 |
| 1264 */ |
| 1265 public synchronized void setFormatWidth(int width) { |
| 1266 properties.setFormatWidth(width); |
| 1267 refreshFormatter(); |
| 1268 } |
| 1269 |
| 1270 /** |
| 1271 * @return The character used for padding. |
| 1272 * @see #setPadCharacter |
| 1273 * @category Padding |
| 1274 * @stable ICU 2.0 |
| 1275 */ |
| 1276 public synchronized char getPadCharacter() { |
| 1277 CharSequence paddingString = exportedProperties.getPadString(); |
| 1278 if (paddingString == null) { |
| 1279 return '.'; // TODO: Is this the correct behavior? |
| 1280 } else { |
| 1281 return paddingString.charAt(0); |
| 1282 } |
| 1283 } |
| 1284 |
| 1285 /** |
| 1286 * <strong>Padding:</strong> Sets the character used to pad numbers that are n
arrower than the |
| 1287 * width specified in {@link #setFormatWidth}. |
| 1288 * |
| 1289 * <p>In the pattern string, the padding character is the token that follows '
*' before or after |
| 1290 * the prefix or suffix. |
| 1291 * |
| 1292 * @param padChar The character used for padding. |
| 1293 * @see #setFormatWidth |
| 1294 * @category Padding |
| 1295 * @stable ICU 2.0 |
| 1296 */ |
| 1297 public synchronized void setPadCharacter(char padChar) { |
| 1298 properties.setPadString(Character.toString(padChar)); |
| 1299 refreshFormatter(); |
| 1300 } |
| 1301 |
| 1302 /** |
| 1303 * @return The position used for padding. |
| 1304 * @see #setPadPosition |
| 1305 * @category Padding |
| 1306 * @stable ICU 2.0 |
| 1307 */ |
| 1308 public synchronized int getPadPosition() { |
| 1309 PadPosition loc = exportedProperties.getPadPosition(); |
| 1310 return (loc == null) ? PAD_BEFORE_PREFIX : loc.toOld(); |
| 1311 } |
| 1312 |
| 1313 /** |
| 1314 * <strong>Padding:</strong> Sets the position where to insert the pad charact
er when narrower |
| 1315 * than the width specified in {@link #setFormatWidth}. For example, consider
the pattern "P123S" |
| 1316 * with padding width 8 and padding char "*". The four positions are: |
| 1317 * |
| 1318 * <ul> |
| 1319 * <li>{@link DecimalFormat#PAD_BEFORE_PREFIX} ⇒ "***P123S" |
| 1320 * <li>{@link DecimalFormat#PAD_AFTER_PREFIX} ⇒ "P***123S" |
| 1321 * <li>{@link DecimalFormat#PAD_BEFORE_SUFFIX} ⇒ "P123***S" |
| 1322 * <li>{@link DecimalFormat#PAD_AFTER_SUFFIX} ⇒ "P123S***" |
| 1323 * </ul> |
| 1324 * |
| 1325 * @param padPos The position used for padding. |
| 1326 * @see #setFormatWidth |
| 1327 * @category Padding |
| 1328 * @stable ICU 2.0 |
| 1329 */ |
| 1330 public synchronized void setPadPosition(int padPos) { |
| 1331 properties.setPadPosition(PadPosition.fromOld(padPos)); |
| 1332 refreshFormatter(); |
| 1333 } |
| 1334 |
| 1335 /** |
| 1336 * @return Whether scientific (exponential) notation is enabled on this format
ter. |
| 1337 * @see #setScientificNotation |
| 1338 * @category ScientificNotation |
| 1339 * @stable ICU 2.0 |
| 1340 */ |
| 1341 public synchronized boolean isScientificNotation() { |
| 1342 return ScientificFormat.useScientificNotation(properties); |
| 1343 } |
| 1344 |
| 1345 /** |
| 1346 * <strong>Scientific Notation:</strong> Sets whether this formatter should pr
int in scientific |
| 1347 * (exponential) notation. For example, if scientific notation is enabled, the
number 123000 will |
| 1348 * be printed as "1.23E5" in locale <em>en-US</em>. A locale-specific symbol i
s used as the |
| 1349 * exponent separator. |
| 1350 * |
| 1351 * <p>Calling <code>df.setScientificNotation(true)</code> is functionally equi
valent to calling |
| 1352 * <code>df.setMinimumExponentDigits(1)</code>. |
| 1353 * |
| 1354 * @param useScientific true to enable scientific notation; false to disable i
t. |
| 1355 * @see #setMinimumExponentDigits |
| 1356 * @category ScientificNotation |
| 1357 * @stable ICU 2.0 |
| 1358 */ |
| 1359 public synchronized void setScientificNotation(boolean useScientific) { |
| 1360 if (useScientific) { |
| 1361 properties.setMinimumExponentDigits(1); |
| 1362 } else { |
| 1363 properties.setMinimumExponentDigits(Properties.DEFAULT_MINIMUM_EXPONENT_DI
GITS); |
| 1364 } |
| 1365 refreshFormatter(); |
| 1366 } |
| 1367 |
| 1368 /** |
| 1369 * @return The minimum number of digits printed in the exponent in scientific
notation. |
| 1370 * @see #setMinimumExponentDigits |
| 1371 * @category ScientificNotation |
| 1372 * @stable ICU 2.0 |
| 1373 */ |
| 1374 public synchronized byte getMinimumExponentDigits() { |
| 1375 return (byte) exportedProperties.getMinimumExponentDigits(); |
| 1376 } |
| 1377 |
| 1378 /** |
| 1379 * <strong>Scientific Notation:</strong> Sets the minimum number of digits to
be printed in the |
| 1380 * exponent. For example, if minimum exponent digits is 3, the number 123000 w
ill be printed as |
| 1381 * "1.23E005". |
| 1382 * |
| 1383 * <p>This setting corresponds to the number of zeros after the 'E' in a patte
rn string such as |
| 1384 * "0.00E000". |
| 1385 * |
| 1386 * @param minExpDig The minimum number of digits in the exponent. |
| 1387 * @category ScientificNotation |
| 1388 * @stable ICU 2.0 |
| 1389 */ |
| 1390 public synchronized void setMinimumExponentDigits(byte minExpDig) { |
| 1391 properties.setMinimumExponentDigits(minExpDig); |
| 1392 refreshFormatter(); |
| 1393 } |
| 1394 |
| 1395 /** |
| 1396 * @return Whether the sign (plus or minus) is always printed in scientific no
tation. |
| 1397 * @see #setExponentSignAlwaysShown |
| 1398 * @category ScientificNotation |
| 1399 * @stable ICU 2.0 |
| 1400 */ |
| 1401 public synchronized boolean isExponentSignAlwaysShown() { |
| 1402 return exportedProperties.getExponentSignAlwaysShown(); |
| 1403 } |
| 1404 |
| 1405 /** |
| 1406 * <strong>Scientific Notation:</strong> Sets whether the sign (plus or minus)
is always to be |
| 1407 * shown in the exponent in scientific notation. For example, if this setting
is enabled, the |
| 1408 * number 123000 will be printed as "1.23E+5" in locale <em>en-US</em>. The nu
mber 0.0000123 will |
| 1409 * always be printed as "1.23E-5" in locale <em>en-US</em> whether or not this
setting is enabled. |
| 1410 * |
| 1411 * <p>This setting corresponds to the '+' in a pattern such as "0.00E+0". |
| 1412 * |
| 1413 * @param expSignAlways true to always shown the sign in the exponent; false t
o show it for |
| 1414 * negatives but not positives. |
| 1415 * @category ScientificNotation |
| 1416 * @stable ICU 2.0 |
| 1417 */ |
| 1418 public synchronized void setExponentSignAlwaysShown(boolean expSignAlways) { |
| 1419 properties.setExponentSignAlwaysShown(expSignAlways); |
| 1420 refreshFormatter(); |
| 1421 } |
| 1422 |
| 1423 /** |
| 1424 * @return Whether or not grouping separators are to be printed in the output. |
| 1425 * @see #setGroupingUsed |
| 1426 * @category Separators |
| 1427 * @stable ICU 2.0 |
| 1428 */ |
| 1429 @Override |
| 1430 public synchronized boolean isGroupingUsed() { |
| 1431 return PositiveDecimalFormat.useGrouping(properties); |
| 1432 } |
| 1433 |
| 1434 /** |
| 1435 * <strong>Grouping:</strong> Sets whether grouping is to be used when formatt
ing numbers. |
| 1436 * Grouping means whether the thousands, millions, billions, and larger powers
of ten should be |
| 1437 * separated by a grouping separator (a comma in <em>en-US</em>). |
| 1438 * |
| 1439 * <p>For example, if grouping is enabled, 12345 will be printed as "12,345" i
n <em>en-US</em>. If |
| 1440 * grouping were disabled, it would instead be printed as simply "12345". |
| 1441 * |
| 1442 * <p>Calling <code>df.setGroupingUsed(true)</code> is functionally equivalent
to setting grouping |
| 1443 * size to 3, as in <code>df.setGroupingSize(3)</code>. |
| 1444 * |
| 1445 * @param enabled true to enable grouping separators; false to disable them. |
| 1446 * @see #setGroupingSize |
| 1447 * @see #setSecondaryGroupingSize |
| 1448 * @category Separators |
| 1449 * @stable ICU 2.0 |
| 1450 */ |
| 1451 @Override |
| 1452 public synchronized void setGroupingUsed(boolean enabled) { |
| 1453 if (enabled) { |
| 1454 // Set to a reasonable default value |
| 1455 properties.setGroupingSize(3); |
| 1456 } else { |
| 1457 properties.setGroupingSize(Properties.DEFAULT_GROUPING_SIZE); |
| 1458 properties.setSecondaryGroupingSize(Properties.DEFAULT_SECONDARY_GROUPING_
SIZE); |
| 1459 } |
| 1460 refreshFormatter(); |
| 1461 } |
| 1462 |
| 1463 /** |
| 1464 * @return The primary grouping size in use. |
| 1465 * @see #setGroupingSize |
| 1466 * @category Separators |
| 1467 * @stable ICU 2.0 |
| 1468 */ |
| 1469 public synchronized int getGroupingSize() { |
| 1470 return exportedProperties.getGroupingSize(); |
| 1471 } |
| 1472 |
| 1473 /** |
| 1474 * <strong>Grouping:</strong> Sets the primary grouping size (distance between
grouping |
| 1475 * separators) used when formatting large numbers. For most locales, this defa
ults to 3: the |
| 1476 * number of digits between the ones and thousands place, between thousands an
d millions, and so |
| 1477 * forth. |
| 1478 * |
| 1479 * <p>For example, with a grouping size of 3, the number 1234567 will be forma
tted as "1,234,567". |
| 1480 * |
| 1481 * <p>Grouping size can also be specified in the pattern: for example, "#,##0"
corresponds to a |
| 1482 * grouping size of 3. |
| 1483 * |
| 1484 * @param width The grouping size to use. |
| 1485 * @see #setSecondaryGroupingSize |
| 1486 * @category Separators |
| 1487 * @stable ICU 2.0 |
| 1488 */ |
| 1489 public synchronized void setGroupingSize(int width) { |
| 1490 properties.setGroupingSize(width); |
| 1491 refreshFormatter(); |
| 1492 } |
| 1493 |
| 1494 /** |
| 1495 * @return The secondary grouping size in use. |
| 1496 * @see #setSecondaryGroupingSize |
| 1497 * @category Separators |
| 1498 * @stable ICU 2.0 |
| 1499 */ |
| 1500 public synchronized int getSecondaryGroupingSize() { |
| 1501 return exportedProperties.getSecondaryGroupingSize(); |
| 1502 } |
| 1503 |
| 1504 /** |
| 1505 * <strong>Grouping:</strong> Sets the secondary grouping size (distance betwe
en grouping |
| 1506 * separators after the first separator) used when formatting large numbers. I
n many south Asian |
| 1507 * locales, this is set to 2. |
| 1508 * |
| 1509 * <p>For example, with primary grouping size 3 and secondary grouping size 2,
the number 1234567 |
| 1510 * will be formatted as "12,34,567". |
| 1511 * |
| 1512 * <p>Grouping size can also be specified in the pattern: for example, "#,##,#
#0" corresponds to a |
| 1513 * primary grouping size of 3 and a secondary grouping size of 2. |
| 1514 * |
| 1515 * @param width The secondary grouping size to use. |
| 1516 * @see #setGroupingSize |
| 1517 * @category Separators |
| 1518 * @stable ICU 2.0 |
| 1519 */ |
| 1520 public synchronized void setSecondaryGroupingSize(int width) { |
| 1521 properties.setSecondaryGroupingSize(width); |
| 1522 refreshFormatter(); |
| 1523 } |
| 1524 |
| 1525 /** |
| 1526 * @return The minimum number of digits before grouping is triggered. |
| 1527 * @see #setMinimumGroupingDigits |
| 1528 * @category Separators |
| 1529 * @internal |
| 1530 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1531 */ |
| 1532 @Deprecated |
| 1533 public synchronized int getMinimumGroupingDigits() { |
| 1534 return properties.getMinimumGroupingDigits(); |
| 1535 } |
| 1536 |
| 1537 /** |
| 1538 * Sets the minimum number of digits that must be before the first grouping se
parator in order for |
| 1539 * the grouping separator to be printed. For example, if minimum grouping digi
ts is set to 2, in |
| 1540 * <em>en-US</em>, 1234 will be printed as "1234" and 12345 will be printed as
"12,345". |
| 1541 * |
| 1542 * @param number The minimum number of digits before grouping is triggered. |
| 1543 * @category Separators |
| 1544 * @internal |
| 1545 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1546 */ |
| 1547 @Deprecated |
| 1548 public synchronized void setMinimumGroupingDigits(int number) { |
| 1549 properties.setMinimumGroupingDigits(number); |
| 1550 refreshFormatter(); |
| 1551 } |
| 1552 |
| 1553 /** |
| 1554 * @return Whether the decimal separator is shown on integers. |
| 1555 * @see #setDecimalSeparatorAlwaysShown |
| 1556 * @category Separators |
| 1557 * @stable ICU 2.0 |
| 1558 */ |
| 1559 public synchronized boolean isDecimalSeparatorAlwaysShown() { |
| 1560 return exportedProperties.getDecimalSeparatorAlwaysShown(); |
| 1561 } |
| 1562 |
| 1563 /** |
| 1564 * <strong>Separators:</strong> Sets whether the decimal separator (a period i
n <em>en-US</em>) is |
| 1565 * shown on integers. For example, if this setting is turned on, formatting 12
3 will result in |
| 1566 * "123." with the decimal separator. |
| 1567 * |
| 1568 * <p>This setting can be specified in the pattern for integer formats: "#,##0
." is an example. |
| 1569 * |
| 1570 * @param value true to always show the decimal separator; false to show it on
ly when there is a |
| 1571 * fraction part of the number. |
| 1572 * @category Separators |
| 1573 * @stable ICU 2.0 |
| 1574 */ |
| 1575 public synchronized void setDecimalSeparatorAlwaysShown(boolean value) { |
| 1576 properties.setDecimalSeparatorAlwaysShown(value); |
| 1577 refreshFormatter(); |
| 1578 } |
| 1579 |
| 1580 /** |
| 1581 * @return The user-specified currency. May be null. |
| 1582 * @see #setCurrency |
| 1583 * @see DecimalFormatSymbols#getCurrency |
| 1584 * @category Currency |
| 1585 * @stable ICU 2.6 |
| 1586 */ |
| 1587 @Override |
| 1588 public synchronized Currency getCurrency() { |
| 1589 return properties.getCurrency(); |
| 1590 } |
| 1591 |
| 1592 /** |
| 1593 * Sets the currency to be used when formatting numbers. The effect is twofold
: |
| 1594 * |
| 1595 * <ol> |
| 1596 * <li>Substitutions for currency symbols in the pattern string will use thi
s currency |
| 1597 * <li>The rounding mode will obey the rules for this currency (see {@link #
setCurrencyUsage}) |
| 1598 * </ol> |
| 1599 * |
| 1600 * <strong>Important:</strong> Displaying the currency in the output requires
that the patter |
| 1601 * associated with this formatter contains a currency symbol '¤'. This will be
the case if the |
| 1602 * instance was created via {@link #getCurrencyInstance} or one of its friends
. |
| 1603 * |
| 1604 * @param currency The currency to use. |
| 1605 * @category Currency |
| 1606 * @stable ICU 2.2 |
| 1607 */ |
| 1608 @Override |
| 1609 public synchronized void setCurrency(Currency currency) { |
| 1610 properties.setCurrency(currency); |
647 // Backwards compatibility: also set the currency in the DecimalFormatSymbol
s | 1611 // Backwards compatibility: also set the currency in the DecimalFormatSymbol
s |
648 if (theCurrency != null) { | 1612 if (currency != null) { |
649 symbols.setCurrency(theCurrency); | 1613 symbols.setCurrency(currency); |
650 String symbol = theCurrency.getName(symbols.getULocale(), Currency.SYMBOL_
NAME, null); | 1614 String symbol = currency.getName(symbols.getULocale(), Currency.SYMBOL_NAM
E, null); |
651 symbols.setCurrencySymbol(symbol); | 1615 symbols.setCurrencySymbol(symbol); |
652 } | 1616 } |
653 refreshFormatter(); | 1617 refreshFormatter(); |
654 } | 1618 } |
655 | 1619 |
656 /** @stable ICU 54 */ | 1620 /** |
657 public synchronized void setCurrencyUsage(CurrencyUsage newUsage) { | 1621 * @return The strategy for rounding currency amounts. |
658 properties.setCurrencyUsage(newUsage); | 1622 * @see #setCurrencyUsage |
659 refreshFormatter(); | 1623 * @category Currency |
660 } | 1624 * @stable ICU 54 |
661 | 1625 */ |
662 /** @stable ICU 54 */ | |
663 public synchronized CurrencyUsage getCurrencyUsage() { | 1626 public synchronized CurrencyUsage getCurrencyUsage() { |
664 return properties.getCurrencyUsage(); | 1627 // CurrencyUsage is not exported, so we have to get it from the input proper
ty bag. |
665 } | 1628 // TODO: Should we export CurrencyUsage instead? |
666 | 1629 CurrencyUsage usage = properties.getCurrencyUsage(); |
667 /** @stable ICU 4.2 */ | 1630 if (usage == null) { |
| 1631 usage = CurrencyUsage.STANDARD; |
| 1632 } |
| 1633 return usage; |
| 1634 } |
| 1635 |
| 1636 /** |
| 1637 * Sets the currency-dependent strategy to use when rounding numbers. There ar
e two strategies: |
| 1638 * |
| 1639 * <ul> |
| 1640 * <li>STANDARD: When the amount displayed is intended for banking statement
s or electronic |
| 1641 * transfer. |
| 1642 * <li>CASH: When the amount displayed is intended to be representable in ph
ysical currency, |
| 1643 * like at a cash register. |
| 1644 * </ul> |
| 1645 * |
| 1646 * CASH mode is relevant in currencies that do not have tender down to the pen
ny. For more |
| 1647 * information on the two rounding strategies, see <a |
| 1648 * href="http://unicode.org/reports/tr35/tr35-numbers.html#Supplemental_Curren
cy_Data">UTS |
| 1649 * #35</a>. If omitted, the strategy defaults to STANDARD. To override currenc
y rounding |
| 1650 * altogether, use {@link #setMinimumFractionDigits} and {@link #setMaximumFra
ctionDigits} or |
| 1651 * {@link #setRoundingIncrement}. |
| 1652 * |
| 1653 * @param usage The strategy to use when rounding in the current currency. |
| 1654 * @category Currency |
| 1655 * @stable ICU 54 |
| 1656 */ |
| 1657 public synchronized void setCurrencyUsage(CurrencyUsage usage) { |
| 1658 properties.setCurrencyUsage(usage); |
| 1659 refreshFormatter(); |
| 1660 } |
| 1661 |
| 1662 /** |
| 1663 * @return The current instance of CurrencyPluralInfo. |
| 1664 * @see #setCurrencyPluralInfo |
| 1665 * @category Currency |
| 1666 * @stable ICU 4.2 |
| 1667 */ |
668 public CurrencyPluralInfo getCurrencyPluralInfo() { | 1668 public CurrencyPluralInfo getCurrencyPluralInfo() { |
| 1669 // CurrencyPluralInfo also is not exported. |
669 return properties.getCurrencyPluralInfo(); | 1670 return properties.getCurrencyPluralInfo(); |
670 } | 1671 } |
671 | 1672 |
672 /** @stable ICU 4.2 */ | 1673 /** |
| 1674 * Sets a custom instance of CurrencyPluralInfo. CurrencyPluralInfo generates
pattern strings for |
| 1675 * printing currency long names. |
| 1676 * |
| 1677 * <p><strong>Most users should not call this method directly.</strong> You sh
ould instead create |
| 1678 * your formatter via <code>NumberFormat.getInstance(NumberFormat.PLURALCURREN
CYSTYLE)</code>. |
| 1679 * |
| 1680 * @param newInfo The CurrencyPluralInfo to use when printing currency long na
mes. |
| 1681 * @category Currency |
| 1682 * @stable ICU 4.2 |
| 1683 */ |
673 public void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) { | 1684 public void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) { |
674 properties.setCurrencyPluralInfo(newInfo); | 1685 properties.setCurrencyPluralInfo(newInfo); |
675 refreshFormatter(); | 1686 refreshFormatter(); |
676 } | 1687 } |
677 | 1688 |
678 /** @stable ICU 3.6 */ | 1689 /** |
| 1690 * @return Whether {@link #parse} will always return a BigDecimal |
| 1691 * @see #setParseBigDecimal |
| 1692 * @category Parsing |
| 1693 * @stable ICU 3.6 |
| 1694 */ |
| 1695 public synchronized boolean isParseBigDecimal() { |
| 1696 return properties.getParseToBigDecimal(); |
| 1697 } |
| 1698 |
| 1699 /** |
| 1700 * Whether to force {@link #parse} to always return a BigDecimal. By default,
{@link #parse} will |
| 1701 * return different data types as follows: |
| 1702 * |
| 1703 * <ol> |
| 1704 * <li>If the number is an integer (has no fraction part), return a Long if
possible, or else a |
| 1705 * BigInteger. |
| 1706 * <li>Otherwise, return a BigDecimal. |
| 1707 * </ol> |
| 1708 * |
| 1709 * If this setting is enabled, a BigDecimal will be returned even if the numbe
r is an integer. |
| 1710 * |
| 1711 * @param value true to cause {@link #parse} to always return a BigDecimal; fa
lse to let {@link |
| 1712 * #parse} return different data types. |
| 1713 * @category Parsing |
| 1714 * @stable ICU 3.6 |
| 1715 */ |
679 public synchronized void setParseBigDecimal(boolean value) { | 1716 public synchronized void setParseBigDecimal(boolean value) { |
680 properties.setParseToBigDecimal(value); | 1717 properties.setParseToBigDecimal(value); |
681 // refreshFormatter() not needed | 1718 // refreshFormatter() not needed |
682 } | 1719 } |
683 | 1720 |
684 /** @stable ICU 3.6 */ | 1721 /** |
685 public synchronized boolean isParseBigDecimal() { | 1722 * @return Always 1000, the default prior to ICU 59. |
686 return properties.getParseToBigDecimal(); | 1723 * @category Parsing |
687 } | 1724 * @deprecated Setting max parse digits has no effect since ICU4J 59. |
688 | 1725 */ |
689 /** | 1726 @Deprecated |
690 * Setting max parse digits has no effect since ICU 59. | 1727 public int getParseMaxDigits() { |
691 * | |
692 * @stable ICU 51 | |
693 */ | |
694 public synchronized void setParseMaxDigits(int _) { | |
695 } | |
696 | |
697 /** | |
698 * Setting max parse digits has no effect since ICU 59. | |
699 * Always returns 1000. | |
700 * | |
701 * @stable ICU 51 | |
702 */ | |
703 public synchronized int getParseMaxDigits() { | |
704 return 1000; | 1728 return 1000; |
705 } | 1729 } |
706 | 1730 |
| 1731 /** |
| 1732 * @param maxDigits Prior to ICU 59, the maximum number of digits in the outpu
t number after |
| 1733 * exponential notation is applied. |
| 1734 * @category Parsing |
| 1735 * @deprecated Setting max parse digits has no effect since ICU4J 59. |
| 1736 */ |
| 1737 @Deprecated |
| 1738 public void setParseMaxDigits(int maxDigits) {} |
| 1739 |
| 1740 /** |
| 1741 * {@inheritDoc} |
| 1742 * |
| 1743 * @category Parsing |
| 1744 * @stable ICU 3.6 |
| 1745 */ |
| 1746 @Override |
| 1747 public synchronized boolean isParseStrict() { |
| 1748 return properties.getParseMode() == Parse.ParseMode.STRICT; |
| 1749 } |
| 1750 |
| 1751 /** |
| 1752 * {@inheritDoc} |
| 1753 * |
| 1754 * @category Parsing |
| 1755 * @stable ICU 3.6 |
| 1756 */ |
707 @Override | 1757 @Override |
708 public synchronized void setParseStrict(boolean parseStrict) { | 1758 public synchronized void setParseStrict(boolean parseStrict) { |
709 Parse.ParseMode mode = parseStrict ? Parse.ParseMode.STRICT : Parse.ParseMod
e.LENIENT; | 1759 Parse.ParseMode mode = parseStrict ? Parse.ParseMode.STRICT : Parse.ParseMod
e.LENIENT; |
710 properties.setParseMode(mode); | 1760 properties.setParseMode(mode); |
711 // refreshFormatter() not needed | 1761 // refreshFormatter() not needed |
712 } | 1762 } |
713 | 1763 |
714 @Override | 1764 /** |
715 public synchronized boolean isParseStrict() { | 1765 * @return Whether parsing should stop before encountering a decimal point and
fraction part. |
716 return properties.getParseMode() == Parse.ParseMode.STRICT; | 1766 * @see #setParseIntegerOnly |
717 } | 1767 * @category Parsing |
718 | 1768 * @stable ICU 2.0 |
| 1769 */ |
| 1770 @Override |
| 1771 public synchronized boolean isParseIntegerOnly() { |
| 1772 return properties.getParseIntegerOnly(); |
| 1773 } |
| 1774 |
| 1775 /** |
| 1776 * <strong>Parsing:</strong> Whether to ignore the fraction part of a number w
hen parsing |
| 1777 * (defaults to false). If a string contains a decimal point, parsing will sto
p before the decimal |
| 1778 * point. Note that determining whether a character is a decimal point depends
on the locale. |
| 1779 * |
| 1780 * <p>For example, in <em>en-US</em>, parsing the string "123.45" will return
the number 123 and |
| 1781 * parse position 3. |
| 1782 * |
| 1783 * <p>This is functionally equivalent to calling {@link #setDecimalPatternMatc
hRequired} and a |
| 1784 * pattern without a decimal point. |
| 1785 * |
| 1786 * @param parseIntegerOnly true to ignore fractional parts of numbers when par
sing; false to |
| 1787 * consume fractional parts. |
| 1788 * @category Parsing |
| 1789 * @stable ICU 2.0 |
| 1790 */ |
719 @Override | 1791 @Override |
720 public synchronized void setParseIntegerOnly(boolean parseIntegerOnly) { | 1792 public synchronized void setParseIntegerOnly(boolean parseIntegerOnly) { |
721 properties.setParseIntegerOnly(parseIntegerOnly); | 1793 properties.setParseIntegerOnly(parseIntegerOnly); |
722 // refreshFormatter() not needed | 1794 // refreshFormatter() not needed |
723 } | 1795 } |
724 | 1796 |
725 @Override | 1797 /** |
726 public synchronized boolean isParseIntegerOnly() { | 1798 * @return Whether the presence of a decimal point must match the pattern. |
727 return properties.getParseIntegerOnly(); | 1799 * @see #setDecimalPatternMatchRequired |
728 } | 1800 * @category Parsing |
729 | 1801 * @stable ICU 54 |
730 /** @stable ICU 2.0 */ | 1802 */ |
731 @Override | 1803 public synchronized boolean isDecimalPatternMatchRequired() { |
732 public Object clone() { | 1804 return properties.getDecimalPatternMatchRequired(); |
733 return new DecimalFormat(this); | 1805 } |
734 } | 1806 |
735 | 1807 /** |
736 /** @stable ICU 2.0 */ | 1808 * <strong>Parsing:</strong> This method is used to either <em>require</em> or
<em>forbid</em> the |
| 1809 * presence of a decimal point in the string being parsed (disabled by default
). This feature was |
| 1810 * designed to be an extra layer of strictness on top of strict parsing, altho
ugh it can be used |
| 1811 * in either lenient mode or strict mode. |
| 1812 * |
| 1813 * <p>To <em>require</em> a decimal point, call this method in combination wit
h either a pattern |
| 1814 * containing a decimal point or with {@link #setDecimalSeparatorAlwaysShown}. |
| 1815 * |
| 1816 * <pre> |
| 1817 * // Require a decimal point in the string being parsed: |
| 1818 * df.applyPattern("#."); |
| 1819 * df.setDecimalPatternMatchRequired(true); |
| 1820 * |
| 1821 * // Alternatively: |
| 1822 * df.setDecimalSeparatorAlwaysShown(true); |
| 1823 * df.setDecimalPatternMatchRequired(true); |
| 1824 * </pre> |
| 1825 * |
| 1826 * To <em>forbid</em> a decimal point, call this method in combination with a
pattern containing |
| 1827 * no decimal point. Alternatively, use {@link #setParseIntegerOnly} for the s
ame behavior without |
| 1828 * depending on the contents of the pattern string. |
| 1829 * |
| 1830 * <pre> |
| 1831 * // Forbid a decimal point in the string being parsed: |
| 1832 * df.applyPattern("#"); |
| 1833 * df.setDecimalPatternMatchRequired(true); |
| 1834 * </pre> |
| 1835 * |
| 1836 * @param value true to either require or forbid the decimal point according t
o the pattern; false |
| 1837 * to disable this feature. |
| 1838 * @see #setParseIntegerOnly |
| 1839 * @category Parsing |
| 1840 * @stable ICU 54 |
| 1841 */ |
| 1842 public synchronized void setDecimalPatternMatchRequired(boolean value) { |
| 1843 properties.setDecimalPatternMatchRequired(value); |
| 1844 refreshFormatter(); |
| 1845 } |
| 1846 |
| 1847 /** |
| 1848 * @return Whether to ignore exponents when parsing. |
| 1849 * @see #setParseNoExponent |
| 1850 * @category Parsing |
| 1851 * @internal |
| 1852 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1853 */ |
| 1854 @Deprecated |
| 1855 public synchronized boolean getParseNoExponent() { |
| 1856 return properties.getParseNoExponent(); |
| 1857 } |
| 1858 |
| 1859 /** |
| 1860 * Specifies whether to stop parsing when an exponent separator is encountered
. For example, |
| 1861 * parses "123E4" to 123 (with parse position 3) instead of 1230000 (with pars
e position 5). |
| 1862 * |
| 1863 * @param value true to prevent exponents from being parsed; false to allow th
em to be parsed. |
| 1864 * @category Parsing |
| 1865 * @internal |
| 1866 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1867 */ |
| 1868 @Deprecated |
| 1869 public synchronized void setParseNoExponent(boolean value) { |
| 1870 properties.setParseNoExponent(value); |
| 1871 refreshFormatter(); |
| 1872 } |
| 1873 |
| 1874 /** |
| 1875 * @return Whether to force case (uppercase/lowercase) to match when parsing. |
| 1876 * @see #setParseNoExponent |
| 1877 * @category Parsing |
| 1878 * @internal |
| 1879 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1880 */ |
| 1881 @Deprecated |
| 1882 public synchronized boolean getParseCaseSensitive() { |
| 1883 return properties.getParseCaseSensitive(); |
| 1884 } |
| 1885 |
| 1886 /** |
| 1887 * Specifies whether parsing should require cases to match in affixes, exponen
t separators, and |
| 1888 * currency codes. Case mapping is performed for each code point using {@link |
| 1889 * UCharacter#foldCase}. |
| 1890 * |
| 1891 * @param value true to force case (uppercase/lowercase) to match when parsing
; false to ignore |
| 1892 * case and perform case folding. |
| 1893 * @category Parsing |
| 1894 * @internal |
| 1895 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1896 */ |
| 1897 @Deprecated |
| 1898 public synchronized void setParseCaseSensitive(boolean value) { |
| 1899 properties.setParseCaseSensitive(value); |
| 1900 refreshFormatter(); |
| 1901 } |
| 1902 |
| 1903 //============================================================================
=========// |
| 1904 // UTILITIES
// |
| 1905 //============================================================================
=========// |
| 1906 |
| 1907 /** |
| 1908 * Tests for equality between this formatter and another formatter. |
| 1909 * |
| 1910 * <p>If two DecimalFormat instances are equal, then they will always produce
the same output. |
| 1911 * However, the reverse is not necessarily true: if two DecimalFormat instance
s always produce the |
| 1912 * same output, they are not necessarily equal. |
| 1913 * |
| 1914 * @stable ICU 2.0 |
| 1915 */ |
737 @Override | 1916 @Override |
738 public synchronized boolean equals(Object obj) { | 1917 public synchronized boolean equals(Object obj) { |
739 if (obj == null) return false; | 1918 if (obj == null) return false; |
740 if (obj == this) return true; | 1919 if (obj == this) return true; |
741 if (!(obj instanceof DecimalFormat)) return false; | 1920 if (!(obj instanceof DecimalFormat)) return false; |
742 DecimalFormat other = (DecimalFormat) obj; | 1921 DecimalFormat other = (DecimalFormat) obj; |
743 return properties.equals(other.properties) && symbols.equals(other.symbols); | 1922 return properties.equals(other.properties) && symbols.equals(other.symbols); |
744 } | 1923 } |
745 | 1924 |
746 /** @stable ICU 2.0 */ | 1925 /** @stable ICU 2.0 */ |
747 @Override | 1926 @Override |
748 public synchronized int hashCode() { | 1927 public synchronized int hashCode() { |
749 return properties.hashCode(); | 1928 return properties.hashCode(); |
750 } | 1929 } |
751 | 1930 |
752 /** @stable ICU 2.0 */ | 1931 private static final ThreadLocal<Properties> threadLocalToPatternProperties = |
| 1932 new ThreadLocal<Properties>() { |
| 1933 @Override |
| 1934 protected Properties initialValue() { |
| 1935 return new Properties(); |
| 1936 } |
| 1937 }; |
| 1938 |
| 1939 @Override |
| 1940 public synchronized String toString() { |
| 1941 return "<DecimalFormat " + symbols.toString() + " " + properties.toString()
+ ">"; |
| 1942 } |
| 1943 |
| 1944 /** |
| 1945 * Serializes this formatter object to a decimal format pattern string. The re
sult of this method |
| 1946 * is guaranteed to be <em>functionally</em> equivalent to the pattern string
used to create this |
| 1947 * instance after incorporating values from the setter methods. |
| 1948 * |
| 1949 * <p>For more information on decimal format pattern strings, see <a |
| 1950 * href="http://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patte
rns">UTS #35</a>. |
| 1951 * |
| 1952 * <p><strong>Important:</strong> Not all properties are capable of being enco
ded in a pattern |
| 1953 * string. See a list of properties in {@link #applyPattern}. |
| 1954 * |
| 1955 * @return A decimal format pattern string. |
| 1956 * @stable ICU 2.0 |
| 1957 */ |
753 public synchronized String toPattern() { | 1958 public synchronized String toPattern() { |
754 // Since we keep the properties object around, use it to generate the patter
n. | 1959 // Pull some properties from exportedProperties and others from properties |
755 return PatternString.propertiesToString(properties); | 1960 // to keep affix patterns intact. In particular, pull rounding properties |
756 } | 1961 // so that CurrencyUsage is reflected properly. |
757 | 1962 // TODO: Consider putting this logic in PatternString.java instead. |
758 /** @stable ICU 2.0 */ | 1963 Properties tprops = threadLocalToPatternProperties.get(); |
| 1964 tprops.copyFrom(properties); |
| 1965 if (com.ibm.icu.impl.number.formatters.CurrencyFormat.useCurrency(properties
)) { |
| 1966 tprops.setMinimumFractionDigits(exportedProperties.getMinimumFractionDigit
s()); |
| 1967 tprops.setMaximumFractionDigits(exportedProperties.getMaximumFractionDigit
s()); |
| 1968 tprops.setRoundingIncrement(exportedProperties.getRoundingIncrement()); |
| 1969 } |
| 1970 return PatternString.propertiesToString(tprops); |
| 1971 } |
| 1972 |
| 1973 /** |
| 1974 * Calls {@link #toPattern} and converts the string to localized notation. For
more information on |
| 1975 * localized notation, see {@link #applyLocalizedPattern}. |
| 1976 * |
| 1977 * @return A decimal format pattern string in localized notation. |
| 1978 * @stable ICU 2.0 |
| 1979 */ |
759 public synchronized String toLocalizedPattern() { | 1980 public synchronized String toLocalizedPattern() { |
760 String pattern = PatternString.propertiesToString(properties); | 1981 String pattern = toPattern(); |
761 return PatternString.convertLocalized(pattern, symbols, true); | 1982 return PatternString.convertLocalized(pattern, symbols, true); |
762 } | 1983 } |
763 | 1984 |
764 /** | 1985 /** |
765 * @internal | 1986 * @internal |
766 * @deprecated This API is ICU internal only. | 1987 * @deprecated This API is ICU internal only. |
767 */ | 1988 */ |
768 @Deprecated | 1989 @Deprecated |
769 public IFixedDecimal getFixedDecimal(double number) { | 1990 public IFixedDecimal getFixedDecimal(double number) { |
770 FormatQuantity fq = FormatQuantitySelector.from(number); | 1991 FormatQuantity4 fq = new FormatQuantity4(number); |
771 formatter.format(fq); | 1992 formatter.format(fq); |
772 return fq; | 1993 return fq; |
773 } | 1994 } |
774 | 1995 |
775 private void refreshFormatter() { | 1996 /** Rebuilds the formatter object from the property bag. */ |
776 try { | 1997 void refreshFormatter() { |
777 formatter = Endpoint.fromBTA(properties, symbols); | 1998 if (exportedProperties == null) { |
778 } catch (ParseException e) { | 1999 // exportedProperties is null only when the formatter is not ready yet. |
779 // For backwards compatibility, convert from ParseException to IllegalArgu
mentException | 2000 // The only time when this happens is during legacy deserialization. |
780 throw new IllegalArgumentException(e); | 2001 return; |
781 } | 2002 } |
782 } | 2003 formatter = Endpoint.fromBTA(properties, symbols); |
783 | 2004 exportedProperties.clear(); |
784 private void setPropertiesFromPattern(String pattern) { | 2005 formatter.export(exportedProperties); |
785 try { | 2006 } |
786 PatternString.parseToExistingProperties(pattern, properties); | 2007 |
787 formatter = Endpoint.fromBTA(properties, symbols); | 2008 /** |
788 } catch (ParseException e) { | 2009 * Updates the property bag with settings from the given pattern. |
789 // For backwards compatibility, convert from ParseException to IllegalArgu
mentException | 2010 * |
790 throw new IllegalArgumentException(e); | 2011 * @param pattern The pattern string to parse. |
791 } | 2012 * @param ignoreRounding Whether to read rounding information from the string.
Set to false if |
| 2013 * CurrencyUsage is to be used instead. |
| 2014 * @see PatternString#parseToExistingProperties |
| 2015 */ |
| 2016 void setPropertiesFromPattern(String pattern, boolean ignoreRounding) { |
| 2017 PatternString.parseToExistingProperties(pattern, properties, ignoreRounding)
; |
| 2018 } |
| 2019 |
| 2020 /** |
| 2021 * @internal |
| 2022 * @deprecated This API is ICU internal only. |
| 2023 */ |
| 2024 @Deprecated |
| 2025 public synchronized void setProperties(PropertySetter func) { |
| 2026 func.set(properties); |
| 2027 refreshFormatter(); |
| 2028 } |
| 2029 |
| 2030 public static interface PropertySetter { |
| 2031 public void set(Properties props); |
792 } | 2032 } |
793 | 2033 |
794 /** | 2034 /** |
795 * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(in
t)} to specify pad | 2035 * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(in
t)} to specify pad |
796 * characters inserted before the prefix. | 2036 * characters inserted before the prefix. |
797 * | 2037 * |
798 * @see #setPadPosition | 2038 * @see #setPadPosition |
799 * @see #getPadPosition | 2039 * @see #getPadPosition |
800 * @see #PAD_AFTER_PREFIX | 2040 * @see #PAD_AFTER_PREFIX |
801 * @see #PAD_BEFORE_SUFFIX | 2041 * @see #PAD_BEFORE_SUFFIX |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
836 * | 2076 * |
837 * @see #setPadPosition | 2077 * @see #setPadPosition |
838 * @see #getPadPosition | 2078 * @see #getPadPosition |
839 * @see #PAD_BEFORE_PREFIX | 2079 * @see #PAD_BEFORE_PREFIX |
840 * @see #PAD_AFTER_PREFIX | 2080 * @see #PAD_AFTER_PREFIX |
841 * @see #PAD_BEFORE_SUFFIX | 2081 * @see #PAD_BEFORE_SUFFIX |
842 * @stable ICU 2.0 | 2082 * @stable ICU 2.0 |
843 */ | 2083 */ |
844 public static final int PAD_AFTER_SUFFIX = 3; | 2084 public static final int PAD_AFTER_SUFFIX = 3; |
845 } | 2085 } |
LEFT | RIGHT |