Save This Page
Home » openjdk-7 » java » text » [javadoc | source]
    1   /*
    2    * Copyright 1996-2005 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   /*
   27    * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
   28    * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
   29    *
   30    *   The original version of this source code and documentation is copyrighted
   31    * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
   32    * materials are provided under terms of a License Agreement between Taligent
   33    * and Sun. This technology is protected by multiple US and International
   34    * patents. This notice and attribution to Taligent may not be removed.
   35    *   Taligent is a registered trademark of Taligent, Inc.
   36    *
   37    */
   38   
   39   package java.text;
   40   
   41   import java.io.InvalidObjectException;
   42   import java.io.IOException;
   43   import java.io.ObjectInputStream;
   44   import java.io.ObjectOutputStream;
   45   import java.math.BigInteger;
   46   import java.math.RoundingMode;
   47   import java.text.spi.NumberFormatProvider;
   48   import java.util.Currency;
   49   import java.util.HashMap;
   50   import java.util.Hashtable;
   51   import java.util.Locale;
   52   import java.util.Map;
   53   import java.util.ResourceBundle;
   54   import java.util.concurrent.atomic.AtomicInteger;
   55   import java.util.concurrent.atomic.AtomicLong;
   56   import java.util.spi.LocaleServiceProvider;
   57   import sun.util.LocaleServiceProviderPool;
   58   import sun.util.resources.LocaleData;
   59   
   60   /**
   61    * <code>NumberFormat</code> is the abstract base class for all number
   62    * formats. This class provides the interface for formatting and parsing
   63    * numbers. <code>NumberFormat</code> also provides methods for determining
   64    * which locales have number formats, and what their names are.
   65    *
   66    * <p>
   67    * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
   68    * Your code can be completely independent of the locale conventions for
   69    * decimal points, thousands-separators, or even the particular decimal
   70    * digits used, or whether the number format is even decimal.
   71    *
   72    * <p>
   73    * To format a number for the current Locale, use one of the factory
   74    * class methods:
   75    * <blockquote>
   76    * <pre>
   77    *  myString = NumberFormat.getInstance().format(myNumber);
   78    * </pre>
   79    * </blockquote>
   80    * If you are formatting multiple numbers, it is
   81    * more efficient to get the format and use it multiple times so that
   82    * the system doesn't have to fetch the information about the local
   83    * language and country conventions multiple times.
   84    * <blockquote>
   85    * <pre>
   86    * NumberFormat nf = NumberFormat.getInstance();
   87    * for (int i = 0; i < myNumber.length; ++i) {
   88    *     output.println(nf.format(myNumber[i]) + "; ");
   89    * }
   90    * </pre>
   91    * </blockquote>
   92    * To format a number for a different Locale, specify it in the
   93    * call to <code>getInstance</code>.
   94    * <blockquote>
   95    * <pre>
   96    * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
   97    * </pre>
   98    * </blockquote>
   99    * You can also use a <code>NumberFormat</code> to parse numbers:
  100    * <blockquote>
  101    * <pre>
  102    * myNumber = nf.parse(myString);
  103    * </pre>
  104    * </blockquote>
  105    * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
  106    * normal number format. Use <code>getIntegerInstance</code> to get an
  107    * integer number format. Use <code>getCurrencyInstance</code> to get the
  108    * currency number format. And use <code>getPercentInstance</code> to get a
  109    * format for displaying percentages. With this format, a fraction like
  110    * 0.53 is displayed as 53%.
  111    *
  112    * <p>
  113    * You can also control the display of numbers with such methods as
  114    * <code>setMinimumFractionDigits</code>.
  115    * If you want even more control over the format or parsing,
  116    * or want to give your users more control,
  117    * you can try casting the <code>NumberFormat</code> you get from the factory methods
  118    * to a <code>DecimalFormat</code>. This will work for the vast majority
  119    * of locales; just remember to put it in a <code>try</code> block in case you
  120    * encounter an unusual one.
  121    *
  122    * <p>
  123    * NumberFormat and DecimalFormat are designed such that some controls
  124    * work for formatting and others work for parsing.  The following is
  125    * the detailed description for each these control methods,
  126    * <p>
  127    * setParseIntegerOnly : only affects parsing, e.g.
  128    * if true,  "3456.78" -> 3456 (and leaves the parse position just after index 6)
  129    * if false, "3456.78" -> 3456.78 (and leaves the parse position just after index 8)
  130    * This is independent of formatting.  If you want to not show a decimal point
  131    * where there might be no digits after the decimal point, use
  132    * setDecimalSeparatorAlwaysShown.
  133    * <p>
  134    * setDecimalSeparatorAlwaysShown : only affects formatting, and only where
  135    * there might be no digits after the decimal point, such as with a pattern
  136    * like "#,##0.##", e.g.,
  137    * if true,  3456.00 -> "3,456."
  138    * if false, 3456.00 -> "3456"
  139    * This is independent of parsing.  If you want parsing to stop at the decimal
  140    * point, use setParseIntegerOnly.
  141    *
  142    * <p>
  143    * You can also use forms of the <code>parse</code> and <code>format</code>
  144    * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
  145    * allow you to:
  146    * <ul>
  147    * <li> progressively parse through pieces of a string
  148    * <li> align the decimal point and other areas
  149    * </ul>
  150    * For example, you can align numbers in two ways:
  151    * <ol>
  152    * <li> If you are using a monospaced font with spacing for alignment,
  153    *      you can pass the <code>FieldPosition</code> in your format call, with
  154    *      <code>field</code> = <code>INTEGER_FIELD</code>. On output,
  155    *      <code>getEndIndex</code> will be set to the offset between the
  156    *      last character of the integer and the decimal. Add
  157    *      (desiredSpaceCount - getEndIndex) spaces at the front of the string.
  158    *
  159    * <li> If you are using proportional fonts,
  160    *      instead of padding with spaces, measure the width
  161    *      of the string in pixels from the start to <code>getEndIndex</code>.
  162    *      Then move the pen by
  163    *      (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
  164    *      It also works where there is no decimal, but possibly additional
  165    *      characters at the end, e.g., with parentheses in negative
  166    *      numbers: "(12)" for -12.
  167    * </ol>
  168    *
  169    * <h4><a name="synchronization">Synchronization</a></h4>
  170    *
  171    * <p>
  172    * Number formats are generally not synchronized.
  173    * It is recommended to create separate format instances for each thread.
  174    * If multiple threads access a format concurrently, it must be synchronized
  175    * externally.
  176    *
  177    * @see          DecimalFormat
  178    * @see          ChoiceFormat
  179    * @author       Mark Davis
  180    * @author       Helena Shih
  181    */
  182   public abstract class NumberFormat extends Format  {
  183   
  184       /**
  185        * Field constant used to construct a FieldPosition object. Signifies that
  186        * the position of the integer part of a formatted number should be returned.
  187        * @see java.text.FieldPosition
  188        */
  189       public static final int INTEGER_FIELD = 0;
  190   
  191       /**
  192        * Field constant used to construct a FieldPosition object. Signifies that
  193        * the position of the fraction part of a formatted number should be returned.
  194        * @see java.text.FieldPosition
  195        */
  196       public static final int FRACTION_FIELD = 1;
  197   
  198       /**
  199        * Sole constructor.  (For invocation by subclass constructors, typically
  200        * implicit.)
  201        */
  202       protected NumberFormat() {
  203       }
  204   
  205       /**
  206        * Formats a number and appends the resulting text to the given string
  207        * buffer.
  208        * The number can be of any subclass of {@link java.lang.Number}.
  209        * <p>
  210        * This implementation extracts the number's value using
  211        * {@link java.lang.Number#longValue()} for all integral type values that
  212        * can be converted to <code>long</code> without loss of information,
  213        * including <code>BigInteger</code> values with a
  214        * {@link java.math.BigInteger#bitLength() bit length} of less than 64,
  215        * and {@link java.lang.Number#doubleValue()} for all other types. It
  216        * then calls
  217        * {@link #format(long,java.lang.StringBuffer,java.text.FieldPosition)}
  218        * or {@link #format(double,java.lang.StringBuffer,java.text.FieldPosition)}.
  219        * This may result in loss of magnitude information and precision for
  220        * <code>BigInteger</code> and <code>BigDecimal</code> values.
  221        * @param number     the number to format
  222        * @param toAppendTo the <code>StringBuffer</code> to which the formatted
  223        *                   text is to be appended
  224        * @param pos        On input: an alignment field, if desired.
  225        *                   On output: the offsets of the alignment field.
  226        * @return           the value passed in as <code>toAppendTo</code>
  227        * @exception        IllegalArgumentException if <code>number</code> is
  228        *                   null or not an instance of <code>Number</code>.
  229        * @exception        NullPointerException if <code>toAppendTo</code> or
  230        *                   <code>pos</code> is null
  231        * @exception        ArithmeticException if rounding is needed with rounding
  232        *                   mode being set to RoundingMode.UNNECESSARY
  233        * @see              java.text.FieldPosition
  234        */
  235       public StringBuffer format(Object number,
  236                                  StringBuffer toAppendTo,
  237                                  FieldPosition pos) {
  238           if (number instanceof Long || number instanceof Integer ||
  239               number instanceof Short || number instanceof Byte ||
  240               number instanceof AtomicInteger || number instanceof AtomicLong ||
  241               (number instanceof BigInteger &&
  242                ((BigInteger)number).bitLength() < 64)) {
  243               return format(((Number)number).longValue(), toAppendTo, pos);
  244           } else if (number instanceof Number) {
  245               return format(((Number)number).doubleValue(), toAppendTo, pos);
  246           } else {
  247               throw new IllegalArgumentException("Cannot format given Object as a Number");
  248           }
  249       }
  250   
  251       /**
  252        * Parses text from a string to produce a <code>Number</code>.
  253        * <p>
  254        * The method attempts to parse text starting at the index given by
  255        * <code>pos</code>.
  256        * If parsing succeeds, then the index of <code>pos</code> is updated
  257        * to the index after the last character used (parsing does not necessarily
  258        * use all characters up to the end of the string), and the parsed
  259        * number is returned. The updated <code>pos</code> can be used to
  260        * indicate the starting point for the next call to this method.
  261        * If an error occurs, then the index of <code>pos</code> is not
  262        * changed, the error index of <code>pos</code> is set to the index of
  263        * the character where the error occurred, and null is returned.
  264        * <p>
  265        * See the {@link #parse(String, ParsePosition)} method for more information
  266        * on number parsing.
  267        *
  268        * @param source A <code>String</code>, part of which should be parsed.
  269        * @param pos A <code>ParsePosition</code> object with index and error
  270        *            index information as described above.
  271        * @return A <code>Number</code> parsed from the string. In case of
  272        *         error, returns null.
  273        * @exception NullPointerException if <code>pos</code> is null.
  274        */
  275       public final Object parseObject(String source, ParsePosition pos) {
  276           return parse(source, pos);
  277       }
  278   
  279      /**
  280        * Specialization of format.
  281        * @exception        ArithmeticException if rounding is needed with rounding
  282        *                   mode being set to RoundingMode.UNNECESSARY
  283        * @see java.text.Format#format
  284        */
  285       public final String format(double number) {
  286           return format(number, new StringBuffer(),
  287                         DontCareFieldPosition.INSTANCE).toString();
  288       }
  289   
  290      /**
  291        * Specialization of format.
  292        * @exception        ArithmeticException if rounding is needed with rounding
  293        *                   mode being set to RoundingMode.UNNECESSARY
  294        * @see java.text.Format#format
  295        */
  296       public final String format(long number) {
  297           return format(number, new StringBuffer(),
  298                         DontCareFieldPosition.INSTANCE).toString();
  299       }
  300   
  301      /**
  302        * Specialization of format.
  303        * @exception        ArithmeticException if rounding is needed with rounding
  304        *                   mode being set to RoundingMode.UNNECESSARY
  305        * @see java.text.Format#format
  306        */
  307       public abstract StringBuffer format(double number,
  308                                           StringBuffer toAppendTo,
  309                                           FieldPosition pos);
  310   
  311      /**
  312        * Specialization of format.
  313        * @exception        ArithmeticException if rounding is needed with rounding
  314        *                   mode being set to RoundingMode.UNNECESSARY
  315        * @see java.text.Format#format
  316        */
  317       public abstract StringBuffer format(long number,
  318                                           StringBuffer toAppendTo,
  319                                           FieldPosition pos);
  320   
  321      /**
  322        * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
  323        * Long.MAX_VALUE] and with no decimals), otherwise a Double.
  324        * If IntegerOnly is set, will stop at a decimal
  325        * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
  326        * after the 1).
  327        * Does not throw an exception; if no object can be parsed, index is
  328        * unchanged!
  329        * @see java.text.NumberFormat#isParseIntegerOnly
  330        * @see java.text.Format#parseObject
  331        */
  332       public abstract Number parse(String source, ParsePosition parsePosition);
  333   
  334       /**
  335        * Parses text from the beginning of the given string to produce a number.
  336        * The method may not use the entire text of the given string.
  337        * <p>
  338        * See the {@link #parse(String, ParsePosition)} method for more information
  339        * on number parsing.
  340        *
  341        * @param source A <code>String</code> whose beginning should be parsed.
  342        * @return A <code>Number</code> parsed from the string.
  343        * @exception ParseException if the beginning of the specified string
  344        *            cannot be parsed.
  345        */
  346       public Number parse(String source) throws ParseException {
  347           ParsePosition parsePosition = new ParsePosition(0);
  348           Number result = parse(source, parsePosition);
  349           if (parsePosition.index == 0) {
  350               throw new ParseException("Unparseable number: \"" + source + "\"",
  351                                        parsePosition.errorIndex);
  352           }
  353           return result;
  354       }
  355   
  356       /**
  357        * Returns true if this format will parse numbers as integers only.
  358        * For example in the English locale, with ParseIntegerOnly true, the
  359        * string "1234." would be parsed as the integer value 1234 and parsing
  360        * would stop at the "." character.  Of course, the exact format accepted
  361        * by the parse operation is locale dependant and determined by sub-classes
  362        * of NumberFormat.
  363        */
  364       public boolean isParseIntegerOnly() {
  365           return parseIntegerOnly;
  366       }
  367   
  368       /**
  369        * Sets whether or not numbers should be parsed as integers only.
  370        * @see #isParseIntegerOnly
  371        */
  372       public void setParseIntegerOnly(boolean value) {
  373           parseIntegerOnly = value;
  374       }
  375   
  376       //============== Locale Stuff =====================
  377   
  378       /**
  379        * Returns a general-purpose number format for the current default locale.
  380        * This is the same as calling
  381        * {@link #getNumberInstance() getNumberInstance()}.
  382        */
  383       public final static NumberFormat getInstance() {
  384           return getInstance(Locale.getDefault(), NUMBERSTYLE);
  385       }
  386   
  387       /**
  388        * Returns a general-purpose number format for the specified locale.
  389        * This is the same as calling
  390        * {@link #getNumberInstance(java.util.Locale) getNumberInstance(inLocale)}.
  391        */
  392       public static NumberFormat getInstance(Locale inLocale) {
  393           return getInstance(inLocale, NUMBERSTYLE);
  394       }
  395   
  396       /**
  397        * Returns a general-purpose number format for the current default locale.
  398        */
  399       public final static NumberFormat getNumberInstance() {
  400           return getInstance(Locale.getDefault(), NUMBERSTYLE);
  401       }
  402   
  403       /**
  404        * Returns a general-purpose number format for the specified locale.
  405        */
  406       public static NumberFormat getNumberInstance(Locale inLocale) {
  407           return getInstance(inLocale, NUMBERSTYLE);
  408       }
  409   
  410       /**
  411        * Returns an integer number format for the current default locale. The
  412        * returned number format is configured to round floating point numbers
  413        * to the nearest integer using half-even rounding (see {@link
  414        * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,
  415        * and to parse only the integer part of an input string (see {@link
  416        * #isParseIntegerOnly isParseIntegerOnly}).
  417        *
  418        * @see #getRoundingMode()
  419        * @return a number format for integer values
  420        * @since 1.4
  421        */
  422       public final static NumberFormat getIntegerInstance() {
  423           return getInstance(Locale.getDefault(), INTEGERSTYLE);
  424       }
  425   
  426       /**
  427        * Returns an integer number format for the specified locale. The
  428        * returned number format is configured to round floating point numbers
  429        * to the nearest integer using half-even rounding (see {@link
  430        * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,
  431        * and to parse only the integer part of an input string (see {@link
  432        * #isParseIntegerOnly isParseIntegerOnly}).
  433        *
  434        * @see #getRoundingMode()
  435        * @return a number format for integer values
  436        * @since 1.4
  437        */
  438       public static NumberFormat getIntegerInstance(Locale inLocale) {
  439           return getInstance(inLocale, INTEGERSTYLE);
  440       }
  441   
  442       /**
  443        * Returns a currency format for the current default locale.
  444        */
  445       public final static NumberFormat getCurrencyInstance() {
  446           return getInstance(Locale.getDefault(), CURRENCYSTYLE);
  447       }
  448   
  449       /**
  450        * Returns a currency format for the specified locale.
  451        */
  452       public static NumberFormat getCurrencyInstance(Locale inLocale) {
  453           return getInstance(inLocale, CURRENCYSTYLE);
  454       }
  455   
  456       /**
  457        * Returns a percentage format for the current default locale.
  458        */
  459       public final static NumberFormat getPercentInstance() {
  460           return getInstance(Locale.getDefault(), PERCENTSTYLE);
  461       }
  462   
  463       /**
  464        * Returns a percentage format for the specified locale.
  465        */
  466       public static NumberFormat getPercentInstance(Locale inLocale) {
  467           return getInstance(inLocale, PERCENTSTYLE);
  468       }
  469   
  470       /**
  471        * Returns a scientific format for the current default locale.
  472        */
  473       /*public*/ final static NumberFormat getScientificInstance() {
  474           return getInstance(Locale.getDefault(), SCIENTIFICSTYLE);
  475       }
  476   
  477       /**
  478        * Returns a scientific format for the specified locale.
  479        */
  480       /*public*/ static NumberFormat getScientificInstance(Locale inLocale) {
  481           return getInstance(inLocale, SCIENTIFICSTYLE);
  482       }
  483   
  484       /**
  485        * Returns an array of all locales for which the
  486        * <code>get*Instance</code> methods of this class can return
  487        * localized instances.
  488        * The returned array represents the union of locales supported by the Java
  489        * runtime and by installed
  490        * {@link java.text.spi.NumberFormatProvider NumberFormatProvider} implementations.
  491        * It must contain at least a <code>Locale</code> instance equal to
  492        * {@link java.util.Locale#US Locale.US}.
  493        *
  494        * @return An array of locales for which localized
  495        *         <code>NumberFormat</code> instances are available.
  496        */
  497       public static Locale[] getAvailableLocales() {
  498           LocaleServiceProviderPool pool =
  499               LocaleServiceProviderPool.getPool(NumberFormatProvider.class);
  500           return pool.getAvailableLocales();
  501       }
  502   
  503       /**
  504        * Overrides hashCode
  505        */
  506       public int hashCode() {
  507           return maximumIntegerDigits * 37 + maxFractionDigits;
  508           // just enough fields for a reasonable distribution
  509       }
  510   
  511       /**
  512        * Overrides equals
  513        */
  514       public boolean equals(Object obj) {
  515           if (obj == null) {
  516               return false;
  517           }
  518           if (this == obj) {
  519               return true;
  520           }
  521           if (getClass() != obj.getClass()) {
  522               return false;
  523           }
  524           NumberFormat other = (NumberFormat) obj;
  525           return (maximumIntegerDigits == other.maximumIntegerDigits
  526               && minimumIntegerDigits == other.minimumIntegerDigits
  527               && maximumFractionDigits == other.maximumFractionDigits
  528               && minimumFractionDigits == other.minimumFractionDigits
  529               && groupingUsed == other.groupingUsed
  530               && parseIntegerOnly == other.parseIntegerOnly);
  531       }
  532   
  533       /**
  534        * Overrides Cloneable
  535        */
  536       public Object clone() {
  537           NumberFormat other = (NumberFormat) super.clone();
  538           return other;
  539       }
  540   
  541       /**
  542        * Returns true if grouping is used in this format. For example, in the
  543        * English locale, with grouping on, the number 1234567 might be formatted
  544        * as "1,234,567". The grouping separator as well as the size of each group
  545        * is locale dependant and is determined by sub-classes of NumberFormat.
  546        * @see #setGroupingUsed
  547        */
  548       public boolean isGroupingUsed() {
  549           return groupingUsed;
  550       }
  551   
  552       /**
  553        * Set whether or not grouping will be used in this format.
  554        * @see #isGroupingUsed
  555        */
  556       public void setGroupingUsed(boolean newValue) {
  557           groupingUsed = newValue;
  558       }
  559   
  560       /**
  561        * Returns the maximum number of digits allowed in the integer portion of a
  562        * number.
  563        * @see #setMaximumIntegerDigits
  564        */
  565       public int getMaximumIntegerDigits() {
  566           return maximumIntegerDigits;
  567       }
  568   
  569       /**
  570        * Sets the maximum number of digits allowed in the integer portion of a
  571        * number. maximumIntegerDigits must be >= minimumIntegerDigits.  If the
  572        * new value for maximumIntegerDigits is less than the current value
  573        * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
  574        * the new value.
  575        * @param newValue the maximum number of integer digits to be shown; if
  576        * less than zero, then zero is used. The concrete subclass may enforce an
  577        * upper limit to this value appropriate to the numeric type being formatted.
  578        * @see #getMaximumIntegerDigits
  579        */
  580       public void setMaximumIntegerDigits(int newValue) {
  581           maximumIntegerDigits = Math.max(0,newValue);
  582           if (minimumIntegerDigits > maximumIntegerDigits) {
  583               minimumIntegerDigits = maximumIntegerDigits;
  584           }
  585       }
  586   
  587       /**
  588        * Returns the minimum number of digits allowed in the integer portion of a
  589        * number.
  590        * @see #setMinimumIntegerDigits
  591        */
  592       public int getMinimumIntegerDigits() {
  593           return minimumIntegerDigits;
  594       }
  595   
  596       /**
  597        * Sets the minimum number of digits allowed in the integer portion of a
  598        * number. minimumIntegerDigits must be <= maximumIntegerDigits.  If the
  599        * new value for minimumIntegerDigits exceeds the current value
  600        * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
  601        * the new value
  602        * @param newValue the minimum number of integer digits to be shown; if
  603        * less than zero, then zero is used. The concrete subclass may enforce an
  604        * upper limit to this value appropriate to the numeric type being formatted.
  605        * @see #getMinimumIntegerDigits
  606        */
  607       public void setMinimumIntegerDigits(int newValue) {
  608           minimumIntegerDigits = Math.max(0,newValue);
  609           if (minimumIntegerDigits > maximumIntegerDigits) {
  610               maximumIntegerDigits = minimumIntegerDigits;
  611           }
  612       }
  613   
  614       /**
  615        * Returns the maximum number of digits allowed in the fraction portion of a
  616        * number.
  617        * @see #setMaximumFractionDigits
  618        */
  619       public int getMaximumFractionDigits() {
  620           return maximumFractionDigits;
  621       }
  622   
  623       /**
  624        * Sets the maximum number of digits allowed in the fraction portion of a
  625        * number. maximumFractionDigits must be >= minimumFractionDigits.  If the
  626        * new value for maximumFractionDigits is less than the current value
  627        * of minimumFractionDigits, then minimumFractionDigits will also be set to
  628        * the new value.
  629        * @param newValue the maximum number of fraction digits to be shown; if
  630        * less than zero, then zero is used. The concrete subclass may enforce an
  631        * upper limit to this value appropriate to the numeric type being formatted.
  632        * @see #getMaximumFractionDigits
  633        */
  634       public void setMaximumFractionDigits(int newValue) {
  635           maximumFractionDigits = Math.max(0,newValue);
  636           if (maximumFractionDigits < minimumFractionDigits) {
  637               minimumFractionDigits = maximumFractionDigits;
  638           }
  639       }
  640   
  641       /**
  642        * Returns the minimum number of digits allowed in the fraction portion of a
  643        * number.
  644        * @see #setMinimumFractionDigits
  645        */
  646       public int getMinimumFractionDigits() {
  647           return minimumFractionDigits;
  648       }
  649   
  650       /**
  651        * Sets the minimum number of digits allowed in the fraction portion of a
  652        * number. minimumFractionDigits must be <= maximumFractionDigits.  If the
  653        * new value for minimumFractionDigits exceeds the current value
  654        * of maximumFractionDigits, then maximumIntegerDigits will also be set to
  655        * the new value
  656        * @param newValue the minimum number of fraction digits to be shown; if
  657        * less than zero, then zero is used. The concrete subclass may enforce an
  658        * upper limit to this value appropriate to the numeric type being formatted.
  659        * @see #getMinimumFractionDigits
  660        */
  661       public void setMinimumFractionDigits(int newValue) {
  662           minimumFractionDigits = Math.max(0,newValue);
  663           if (maximumFractionDigits < minimumFractionDigits) {
  664               maximumFractionDigits = minimumFractionDigits;
  665           }
  666       }
  667   
  668       /**
  669        * Gets the currency used by this number format when formatting
  670        * currency values. The initial value is derived in a locale dependent
  671        * way. The returned value may be null if no valid
  672        * currency could be determined and no currency has been set using
  673        * {@link #setCurrency(java.util.Currency) setCurrency}.
  674        * <p>
  675        * The default implementation throws
  676        * <code>UnsupportedOperationException</code>.
  677        *
  678        * @return the currency used by this number format, or <code>null</code>
  679        * @exception UnsupportedOperationException if the number format class
  680        * doesn't implement currency formatting
  681        * @since 1.4
  682        */
  683       public Currency getCurrency() {
  684           throw new UnsupportedOperationException();
  685       }
  686   
  687       /**
  688        * Sets the currency used by this number format when formatting
  689        * currency values. This does not update the minimum or maximum
  690        * number of fraction digits used by the number format.
  691        * <p>
  692        * The default implementation throws
  693        * <code>UnsupportedOperationException</code>.
  694        *
  695        * @param currency the new currency to be used by this number format
  696        * @exception UnsupportedOperationException if the number format class
  697        * doesn't implement currency formatting
  698        * @exception NullPointerException if <code>currency</code> is null
  699        * @since 1.4
  700        */
  701       public void setCurrency(Currency currency) {
  702           throw new UnsupportedOperationException();
  703       }
  704   
  705       /**
  706        * Gets the {@link java.math.RoundingMode} used in this NumberFormat.
  707        * The default implementation of this method in NumberFormat
  708        * always throws {@link java.lang.UnsupportedOperationException}.
  709        * Subclasses which handle different rounding modes should override
  710        * this method.
  711        *
  712        * @exception UnsupportedOperationException The default implementation
  713        *     always throws this exception
  714        * @return The <code>RoundingMode</code> used for this NumberFormat.
  715        * @see #setRoundingMode(RoundingMode)
  716        * @since 1.6
  717        */
  718       public RoundingMode getRoundingMode() {
  719           throw new UnsupportedOperationException();
  720       }
  721   
  722       /**
  723        * Sets the {@link java.math.RoundingMode} used in this NumberFormat.
  724        * The default implementation of this method in NumberFormat always
  725        * throws {@link java.lang.UnsupportedOperationException}.
  726        * Subclasses which handle different rounding modes should override
  727        * this method.
  728        *
  729        * @exception UnsupportedOperationException The default implementation
  730        *     always throws this exception
  731        * @exception NullPointerException if <code>roundingMode</code> is null
  732        * @param roundingMode The <code>RoundingMode</code> to be used
  733        * @see #getRoundingMode()
  734        * @since 1.6
  735        */
  736       public void setRoundingMode(RoundingMode roundingMode) {
  737           throw new UnsupportedOperationException();
  738       }
  739   
  740       // =======================privates===============================
  741   
  742       private static NumberFormat getInstance(Locale desiredLocale,
  743                                              int choice) {
  744           // Check whether a provider can provide an implementation that's closer
  745           // to the requested locale than what the Java runtime itself can provide.
  746           LocaleServiceProviderPool pool =
  747               LocaleServiceProviderPool.getPool(NumberFormatProvider.class);
  748           if (pool.hasProviders()) {
  749               NumberFormat providersInstance = pool.getLocalizedObject(
  750                                       NumberFormatGetter.INSTANCE,
  751                                       desiredLocale,
  752                                       choice);
  753               if (providersInstance != null) {
  754                   return providersInstance;
  755               }
  756           }
  757   
  758           /* try the cache first */
  759           String[] numberPatterns = (String[])cachedLocaleData.get(desiredLocale);
  760           if (numberPatterns == null) { /* cache miss */
  761               ResourceBundle resource = LocaleData.getNumberFormatData(desiredLocale);
  762               numberPatterns = resource.getStringArray("NumberPatterns");
  763               /* update cache */
  764               cachedLocaleData.put(desiredLocale, numberPatterns);
  765           }
  766   
  767           DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(desiredLocale);
  768           int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE : choice;
  769           DecimalFormat format = new DecimalFormat(numberPatterns[entry], symbols);
  770   
  771           if (choice == INTEGERSTYLE) {
  772               format.setMaximumFractionDigits(0);
  773               format.setDecimalSeparatorAlwaysShown(false);
  774               format.setParseIntegerOnly(true);
  775           } else if (choice == CURRENCYSTYLE) {
  776               format.adjustForCurrencyDefaultFractionDigits();
  777           }
  778   
  779           return format;
  780       }
  781   
  782       /**
  783        * First, read in the default serializable data.
  784        *
  785        * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
  786        * the stream was written by JDK 1.1,
  787        * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
  788        * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
  789        * since the <code>int</code> fields were not present in JDK 1.1.
  790        * Finally, set serialVersionOnStream back to the maximum allowed value so that
  791        * default serialization will work properly if this object is streamed out again.
  792        *
  793        * <p>If <code>minimumIntegerDigits</code> is greater than
  794        * <code>maximumIntegerDigits</code> or <code>minimumFractionDigits</code>
  795        * is greater than <code>maximumFractionDigits</code>, then the stream data
  796        * is invalid and this method throws an <code>InvalidObjectException</code>.
  797        * In addition, if any of these values is negative, then this method throws
  798        * an <code>InvalidObjectException</code>.
  799        *
  800        * @since 1.2
  801        */
  802       private void readObject(ObjectInputStream stream)
  803            throws IOException, ClassNotFoundException
  804       {
  805           stream.defaultReadObject();
  806           if (serialVersionOnStream < 1) {
  807               // Didn't have additional int fields, reassign to use them.
  808               maximumIntegerDigits = maxIntegerDigits;
  809               minimumIntegerDigits = minIntegerDigits;
  810               maximumFractionDigits = maxFractionDigits;
  811               minimumFractionDigits = minFractionDigits;
  812           }
  813           if (minimumIntegerDigits > maximumIntegerDigits ||
  814               minimumFractionDigits > maximumFractionDigits ||
  815               minimumIntegerDigits < 0 || minimumFractionDigits < 0) {
  816               throw new InvalidObjectException("Digit count range invalid");
  817           }
  818           serialVersionOnStream = currentSerialVersion;
  819       }
  820   
  821       /**
  822        * Write out the default serializable data, after first setting
  823        * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be
  824        * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
  825        * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
  826        * with the JDK 1.1 version of the stream format.
  827        *
  828        * @since 1.2
  829        */
  830       private void writeObject(ObjectOutputStream stream)
  831            throws IOException
  832       {
  833           maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ?
  834                              Byte.MAX_VALUE : (byte)maximumIntegerDigits;
  835           minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ?
  836                              Byte.MAX_VALUE : (byte)minimumIntegerDigits;
  837           maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ?
  838                               Byte.MAX_VALUE : (byte)maximumFractionDigits;
  839           minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ?
  840                               Byte.MAX_VALUE : (byte)minimumFractionDigits;
  841           stream.defaultWriteObject();
  842       }
  843   
  844       /**
  845        * Cache to hold the NumberPatterns of a Locale.
  846        */
  847       private static final Hashtable cachedLocaleData = new Hashtable(3);
  848   
  849       // Constants used by factory methods to specify a style of format.
  850       private static final int NUMBERSTYLE = 0;
  851       private static final int CURRENCYSTYLE = 1;
  852       private static final int PERCENTSTYLE = 2;
  853       private static final int SCIENTIFICSTYLE = 3;
  854       private static final int INTEGERSTYLE = 4;
  855   
  856       /**
  857        * True if the grouping (i.e. thousands) separator is used when
  858        * formatting and parsing numbers.
  859        *
  860        * @serial
  861        * @see #isGroupingUsed
  862        */
  863       private boolean groupingUsed = true;
  864   
  865       /**
  866        * The maximum number of digits allowed in the integer portion of a
  867        * number.  <code>maxIntegerDigits</code> must be greater than or equal to
  868        * <code>minIntegerDigits</code>.
  869        * <p>
  870        * <strong>Note:</strong> This field exists only for serialization
  871        * compatibility with JDK 1.1.  In Java platform 2 v1.2 and higher, the new
  872        * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.
  873        * When writing to a stream, <code>maxIntegerDigits</code> is set to
  874        * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
  875        * whichever is smaller.  When reading from a stream, this field is used
  876        * only if <code>serialVersionOnStream</code> is less than 1.
  877        *
  878        * @serial
  879        * @see #getMaximumIntegerDigits
  880        */
  881       private byte    maxIntegerDigits = 40;
  882   
  883       /**
  884        * The minimum number of digits allowed in the integer portion of a
  885        * number.  <code>minimumIntegerDigits</code> must be less than or equal to
  886        * <code>maximumIntegerDigits</code>.
  887        * <p>
  888        * <strong>Note:</strong> This field exists only for serialization
  889        * compatibility with JDK 1.1.  In Java platform 2 v1.2 and higher, the new
  890        * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.
  891        * When writing to a stream, <code>minIntegerDigits</code> is set to
  892        * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
  893        * whichever is smaller.  When reading from a stream, this field is used
  894        * only if <code>serialVersionOnStream</code> is less than 1.
  895        *
  896        * @serial
  897        * @see #getMinimumIntegerDigits
  898        */
  899       private byte    minIntegerDigits = 1;
  900   
  901       /**
  902        * The maximum number of digits allowed in the fractional portion of a
  903        * number.  <code>maximumFractionDigits</code> must be greater than or equal to
  904        * <code>minimumFractionDigits</code>.
  905        * <p>
  906        * <strong>Note:</strong> This field exists only for serialization
  907        * compatibility with JDK 1.1.  In Java platform 2 v1.2 and higher, the new
  908        * <code>int</code> field <code>maximumFractionDigits</code> is used instead.
  909        * When writing to a stream, <code>maxFractionDigits</code> is set to
  910        * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
  911        * whichever is smaller.  When reading from a stream, this field is used
  912        * only if <code>serialVersionOnStream</code> is less than 1.
  913        *
  914        * @serial
  915        * @see #getMaximumFractionDigits
  916        */
  917       private byte    maxFractionDigits = 3;    // invariant, >= minFractionDigits
  918   
  919       /**
  920        * The minimum number of digits allowed in the fractional portion of a
  921        * number.  <code>minimumFractionDigits</code> must be less than or equal to
  922        * <code>maximumFractionDigits</code>.
  923        * <p>
  924        * <strong>Note:</strong> This field exists only for serialization
  925        * compatibility with JDK 1.1.  In Java platform 2 v1.2 and higher, the new
  926        * <code>int</code> field <code>minimumFractionDigits</code> is used instead.
  927        * When writing to a stream, <code>minFractionDigits</code> is set to
  928        * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
  929        * whichever is smaller.  When reading from a stream, this field is used
  930        * only if <code>serialVersionOnStream</code> is less than 1.
  931        *
  932        * @serial
  933        * @see #getMinimumFractionDigits
  934        */
  935       private byte    minFractionDigits = 0;
  936   
  937       /**
  938        * True if this format will parse numbers as integers only.
  939        *
  940        * @serial
  941        * @see #isParseIntegerOnly
  942        */
  943       private boolean parseIntegerOnly = false;
  944   
  945       // new fields for 1.2.  byte is too small for integer digits.
  946   
  947       /**
  948        * The maximum number of digits allowed in the integer portion of a
  949        * number.  <code>maximumIntegerDigits</code> must be greater than or equal to
  950        * <code>minimumIntegerDigits</code>.
  951        *
  952        * @serial
  953        * @since 1.2
  954        * @see #getMaximumIntegerDigits
  955        */
  956       private int    maximumIntegerDigits = 40;
  957   
  958       /**
  959        * The minimum number of digits allowed in the integer portion of a
  960        * number.  <code>minimumIntegerDigits</code> must be less than or equal to
  961        * <code>maximumIntegerDigits</code>.
  962        *
  963        * @serial
  964        * @since 1.2
  965        * @see #getMinimumIntegerDigits
  966        */
  967       private int    minimumIntegerDigits = 1;
  968   
  969       /**
  970        * The maximum number of digits allowed in the fractional portion of a
  971        * number.  <code>maximumFractionDigits</code> must be greater than or equal to
  972        * <code>minimumFractionDigits</code>.
  973        *
  974        * @serial
  975        * @since 1.2
  976        * @see #getMaximumFractionDigits
  977        */
  978       private int    maximumFractionDigits = 3;    // invariant, >= minFractionDigits
  979   
  980       /**
  981        * The minimum number of digits allowed in the fractional portion of a
  982        * number.  <code>minimumFractionDigits</code> must be less than or equal to
  983        * <code>maximumFractionDigits</code>.
  984        *
  985        * @serial
  986        * @since 1.2
  987        * @see #getMinimumFractionDigits
  988        */
  989       private int    minimumFractionDigits = 0;
  990   
  991       static final int currentSerialVersion = 1;
  992   
  993       /**
  994        * Describes the version of <code>NumberFormat</code> present on the stream.
  995        * Possible values are:
  996        * <ul>
  997        * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.
  998        *     In this version, the <code>int</code> fields such as
  999        *     <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>
 1000        *     fields such as <code>maxIntegerDigits</code> are used instead.
 1001        *
 1002        * <li><b>1</b>: the 1.2 version of the stream format.  The values of the
 1003        *     <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,
 1004        *     and the <code>int</code> fields such as <code>maximumIntegerDigits</code>
 1005        *     are used instead.
 1006        * </ul>
 1007        * When streaming out a <code>NumberFormat</code>, the most recent format
 1008        * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
 1009        * is always written.
 1010        *
 1011        * @serial
 1012        * @since 1.2
 1013        */
 1014       private int serialVersionOnStream = currentSerialVersion;
 1015   
 1016       // Removed "implements Cloneable" clause.  Needs to update serialization
 1017       // ID for backward compatibility.
 1018       static final long serialVersionUID = -2308460125733713944L;
 1019   
 1020   
 1021       //
 1022       // class for AttributedCharacterIterator attributes
 1023       //
 1024       /**
 1025        * Defines constants that are used as attribute keys in the
 1026        * <code>AttributedCharacterIterator</code> returned
 1027        * from <code>NumberFormat.formatToCharacterIterator</code> and as
 1028        * field identifiers in <code>FieldPosition</code>.
 1029        *
 1030        * @since 1.4
 1031        */
 1032       public static class Field extends Format.Field {
 1033   
 1034           // Proclaim serial compatibility with 1.4 FCS
 1035           private static final long serialVersionUID = 7494728892700160890L;
 1036   
 1037           // table of all instances in this class, used by readResolve
 1038           private static final Map instanceMap = new HashMap(11);
 1039   
 1040           /**
 1041            * Creates a Field instance with the specified
 1042            * name.
 1043            *
 1044            * @param name Name of the attribute
 1045            */
 1046           protected Field(String name) {
 1047               super(name);
 1048               if (this.getClass() == NumberFormat.Field.class) {
 1049                   instanceMap.put(name, this);
 1050               }
 1051           }
 1052   
 1053           /**
 1054            * Resolves instances being deserialized to the predefined constants.
 1055            *
 1056            * @throws InvalidObjectException if the constant could not be resolved.
 1057            * @return resolved NumberFormat.Field constant
 1058            */
 1059           protected Object readResolve() throws InvalidObjectException {
 1060               if (this.getClass() != NumberFormat.Field.class) {
 1061                   throw new InvalidObjectException("subclass didn't correctly implement readResolve");
 1062               }
 1063   
 1064               Object instance = instanceMap.get(getName());
 1065               if (instance != null) {
 1066                   return instance;
 1067               } else {
 1068                   throw new InvalidObjectException("unknown attribute name");
 1069               }
 1070           }
 1071   
 1072           /**
 1073            * Constant identifying the integer field.
 1074            */
 1075           public static final Field INTEGER = new Field("integer");
 1076   
 1077           /**
 1078            * Constant identifying the fraction field.
 1079            */
 1080           public static final Field FRACTION = new Field("fraction");
 1081   
 1082           /**
 1083            * Constant identifying the exponent field.
 1084            */
 1085           public static final Field EXPONENT = new Field("exponent");
 1086   
 1087           /**
 1088            * Constant identifying the decimal separator field.
 1089            */
 1090           public static final Field DECIMAL_SEPARATOR =
 1091                               new Field("decimal separator");
 1092   
 1093           /**
 1094            * Constant identifying the sign field.
 1095            */
 1096           public static final Field SIGN = new Field("sign");
 1097   
 1098           /**
 1099            * Constant identifying the grouping separator field.
 1100            */
 1101           public static final Field GROUPING_SEPARATOR =
 1102                               new Field("grouping separator");
 1103   
 1104           /**
 1105            * Constant identifying the exponent symbol field.
 1106            */
 1107           public static final Field EXPONENT_SYMBOL = new
 1108                               Field("exponent symbol");
 1109   
 1110           /**
 1111            * Constant identifying the percent field.
 1112            */
 1113           public static final Field PERCENT = new Field("percent");
 1114   
 1115           /**
 1116            * Constant identifying the permille field.
 1117            */
 1118           public static final Field PERMILLE = new Field("per mille");
 1119   
 1120           /**
 1121            * Constant identifying the currency field.
 1122            */
 1123           public static final Field CURRENCY = new Field("currency");
 1124   
 1125           /**
 1126            * Constant identifying the exponent sign field.
 1127            */
 1128           public static final Field EXPONENT_SIGN = new Field("exponent sign");
 1129       }
 1130   
 1131       /**
 1132        * Obtains a NumberFormat instance from a NumberFormatProvider implementation.
 1133        */
 1134       private static class NumberFormatGetter
 1135           implements LocaleServiceProviderPool.LocalizedObjectGetter<NumberFormatProvider,
 1136                                                                      NumberFormat> {
 1137           private static final NumberFormatGetter INSTANCE = new NumberFormatGetter();
 1138   
 1139           public NumberFormat getObject(NumberFormatProvider numberFormatProvider,
 1140                                   Locale locale,
 1141                                   String key,
 1142                                   Object... params) {
 1143               assert params.length == 1;
 1144               int choice = (Integer)params[0];
 1145   
 1146               switch (choice) {
 1147               case NUMBERSTYLE:
 1148                   return numberFormatProvider.getNumberInstance(locale);
 1149               case PERCENTSTYLE:
 1150                   return numberFormatProvider.getPercentInstance(locale);
 1151               case CURRENCYSTYLE:
 1152                   return numberFormatProvider.getCurrencyInstance(locale);
 1153               case INTEGERSTYLE:
 1154                   return numberFormatProvider.getIntegerInstance(locale);
 1155               default:
 1156                   assert false : choice;
 1157               }
 1158   
 1159               return null;
 1160           }
 1161       }
 1162   }

Save This Page
Home » openjdk-7 » java » text » [javadoc | source]