Source for java.text.NumberFormat

   1: /* NumberFormat.java -- Formats and parses numbers
   2:    Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10:  
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.text;
  40: 
  41: import java.io.IOException;
  42: import java.io.InvalidObjectException;
  43: import java.io.ObjectInputStream;
  44: import java.io.ObjectOutputStream;
  45: import java.util.Currency;
  46: import java.util.Locale;
  47: import java.util.MissingResourceException;
  48: import java.util.ResourceBundle;
  49: 
  50: /**
  51:  * This is the abstract superclass of all classes which format and 
  52:  * parse numeric values such as decimal numbers, integers, currency values,
  53:  * and percentages.  These classes perform their parsing and formatting
  54:  * in a locale specific manner, accounting for such items as differing
  55:  * currency symbols and thousands separators.
  56:  * <p>
  57:  * To create an instance of a concrete subclass of <code>NumberFormat</code>,
  58:  * do not call a class constructor directly.  Instead, use one of the
  59:  * static factory methods in this class such as 
  60:  * <code>getCurrencyInstance</code>.
  61:  * 
  62:  * @author Tom Tromey (tromey@cygnus.com)
  63:  * @author Aaron M. Renn (arenn@urbanophile.com)
  64:  * @date March 4, 1999
  65:  */
  66: /* Written using "Java Class Libraries", 2nd edition, plus online
  67:  * API docs for JDK 1.2 from http://www.javasoft.com.
  68:  * Status:  Believed complete and correct to 1.2, except getAvailableLocales.
  69:  */
  70: public abstract class NumberFormat extends Format implements Cloneable
  71: {
  72:   /**
  73:    * This is a constant used to create a <code>FieldPosition</code> object
  74:    * that will return the integer portion of a formatted number.
  75:    */
  76:   public static final int INTEGER_FIELD = 0;
  77: 
  78:   /**
  79:    * This is a constant used to create a <code>FieldPosition</code> object
  80:    * that will return the fractional portion of a formatted number.
  81:    */
  82:   public static final int FRACTION_FIELD = 1;
  83: 
  84:   public static class Field extends Format.Field
  85:   {
  86:     static final long serialVersionUID = 7494728892700160890L;
  87: 
  88:     /**
  89:      * Attribute set to all characters containing digits of the integer
  90:      * part.
  91:      */
  92:     public static final NumberFormat.Field INTEGER
  93:       = new Field("integer");
  94: 
  95:     /**
  96:      * Attribute set to all characters containing digits of the fractional
  97:      * part.
  98:      */
  99:     public static final NumberFormat.Field FRACTION
 100:       = new Field("fraction");
 101: 
 102:     /**
 103:      * Attribute set to all characters containing digits of the exponential
 104:      * part.
 105:      */
 106:     public static final NumberFormat.Field EXPONENT
 107:       = new Field("exponent");
 108: 
 109:     /**
 110:      * Attribute set to all characters containing a decimal separator.
 111:      */
 112:     public static final NumberFormat.Field DECIMAL_SEPARATOR
 113:       = new Field("decimal separator");
 114: 
 115:     /**
 116:      * Attribute set to all characters containing a sign (plus or minus).
 117:      */
 118:     public static final NumberFormat.Field SIGN
 119:       = new Field("sign");
 120: 
 121:     /**
 122:      * Attribute set to all characters containing a grouping separator (e.g.
 123:      * a comma, a white space,...).
 124:      */
 125:     public static final NumberFormat.Field GROUPING_SEPARATOR
 126:       = new Field("grouping separator");
 127: 
 128:     /**
 129:      * Attribute set to all characters containing an exponential symbol (e.g.
 130:      * 'E')
 131:      */
 132:     public static final NumberFormat.Field EXPONENT_SYMBOL
 133:       = new Field("exponent symbol");
 134: 
 135:     /**
 136:      * Attribute set to all characters containing a percent symbol (e.g. '%')
 137:      */
 138:     public static final NumberFormat.Field PERCENT
 139:       = new Field("percent");
 140: 
 141:     /**
 142:      * Attribute set to all characters containing a permille symbol.
 143:      */
 144:     public static final NumberFormat.Field PERMILLE
 145:       = new Field("permille");
 146: 
 147:     /**
 148:      * Attribute set to all characters containing the currency unit.
 149:      */
 150:     public static final NumberFormat.Field CURRENCY
 151:       = new Field("currency");
 152: 
 153:     /**
 154:      * Attribute set to all characters containing the exponent sign.
 155:      */
 156:     public static final NumberFormat.Field EXPONENT_SIGN
 157:       = new Field("exponent sign");
 158: 
 159:     /**
 160:      * Private fields to register all fields contained in this descriptor.
 161:      */
 162:     private static final NumberFormat.Field[] allFields =
 163:     {
 164:       INTEGER, FRACTION, EXPONENT, DECIMAL_SEPARATOR, SIGN,
 165:       GROUPING_SEPARATOR, EXPONENT_SYMBOL, PERCENT,
 166:       PERMILLE, CURRENCY, EXPONENT_SIGN
 167:     };
 168: 
 169:     /**
 170:      * This constructor is only used by the deserializer. Without it,
 171:      * it would fail to construct a valid object.
 172:      */
 173:     private Field()
 174:     {
 175:       super("");
 176:     }
 177: 
 178:     /**
 179:      * Create a Field instance with the specified field name.
 180:      *
 181:      * @param field_name Field name for the new Field instance.
 182:      */
 183:     protected Field(String field_name)
 184:     {
 185:       super (field_name);
 186:     }
 187: 
 188:     /**
 189:      * This function is used by the deserializer to know which object
 190:      * to use when it encounters an encoded NumberFormat.Field in a 
 191:      * serialization stream. If the stream is valid it should return
 192:      * one of the above field. In the other case we throw an exception.
 193:      *
 194:      * @return a valid official NumberFormat.Field instance.
 195:      *
 196:      * @throws InvalidObjectException if the field name is invalid.
 197:      */
 198:     protected Object readResolve() throws InvalidObjectException
 199:     {
 200:       String s = getName();
 201:       for (int i = 0; i < allFields.length; i++)
 202:     if (s.equals(allFields[i].getName()))
 203:       return allFields[i];
 204: 
 205:       throw new InvalidObjectException("no such NumberFormat field called "
 206:                        + s);
 207:     }
 208:   }
 209: 
 210:   /**
 211:    * This method is a specialization of the format method that performs
 212:    * a simple formatting of the specified <code>long</code> number.
 213:    *
 214:    * @param number The <code>long</code> to format.
 215:    *
 216:    * @return The formatted number
 217:    */
 218:   public final String format (long number)
 219:   {
 220:     StringBuffer sbuf = new StringBuffer(50);
 221:     format (number, sbuf, null);
 222:     return sbuf.toString();
 223:   }
 224: 
 225:   public final StringBuffer format (Object obj, StringBuffer sbuf,
 226:                     FieldPosition pos)
 227:   {
 228:     if (obj instanceof Number)
 229:       return format(((Number) obj).doubleValue(), sbuf, pos);
 230:     else
 231:       throw new IllegalArgumentException 
 232:     ("Cannot format given Object as a Number");
 233:   }
 234: 
 235:   /**
 236:    * This method formats the specified <code>double</code> and appends it to
 237:    * a <code>StringBuffer</code>.
 238:    * 
 239:    * @param number The <code>double</code> to format.
 240:    * @param sbuf The <code>StringBuffer</code> to append the formatted number 
 241:    *             to.
 242:    * @param pos The desired <code>FieldPosition</code>.
 243:    *
 244:    * @return The <code>StringBuffer</code> with the appended number.
 245:    */
 246:   public abstract StringBuffer format (double number,
 247:                        StringBuffer sbuf, FieldPosition pos);
 248: 
 249:   /**
 250:    * This method formats the specified <code>long</code> and appends it to
 251:    * a <code>StringBuffer</code>.
 252:    * 
 253:    * @param number The <code>long</code> to format.
 254:    * @param sbuf The <code>StringBuffer</code> to append the formatted number 
 255:    *             to.
 256:    * @param pos The desired <code>FieldPosition</code>.
 257:    *
 258:    * @return The <code>StringBuffer</code> with the appended number.
 259:    */
 260:   public abstract StringBuffer format (long number,
 261:                        StringBuffer sbuf, FieldPosition pos);
 262: 
 263:   /**
 264:    * This method tests the specified object for equality against this object.
 265:    * This will be <code>true</code> if the following conditions are met:
 266:    * <p>
 267:    * <ul>
 268:    * <li>The specified object is not <code>null</code>.
 269:    * <li>The specified object is an instance of <code>NumberFormat</code>.
 270:    * </ul>
 271:    * <p>
 272:    * Since this method does not test much, it is highly advised that 
 273:    * concrete subclasses override this method.
 274:    *
 275:    * @param obj The <code>Object</code> to test against equality with
 276:    *            this object. 
 277:    * 
 278:    * @return <code>true</code> if the specified object is equal to
 279:    * this object, <code>false</code> otherwise. 
 280:    */
 281:   public boolean equals (Object obj)
 282:   {
 283:     if (! (obj instanceof NumberFormat))
 284:       return false;
 285:     NumberFormat nf = (NumberFormat) obj;
 286:     return (groupingUsed == nf.groupingUsed
 287:         && maximumFractionDigits == nf.maximumFractionDigits
 288:         && maximumIntegerDigits == nf.maximumIntegerDigits
 289:         && minimumFractionDigits == nf.minimumFractionDigits
 290:         && minimumIntegerDigits == nf.minimumIntegerDigits
 291:         && parseIntegerOnly == nf.parseIntegerOnly);
 292:   }
 293: 
 294:   /**
 295:    * This method returns a list of locales for which concrete instances
 296:    * of <code>NumberFormat</code> subclasses may be created.
 297:    *
 298:    * @return The list of available locales.
 299:    */
 300:   public static Locale[] getAvailableLocales ()
 301:   {
 302:     Locale[] list = new Locale[1];
 303:     list[0] = Locale.US;
 304:     return list;
 305:   }
 306: 
 307:   private static NumberFormat computeInstance(Locale loc, String resource,
 308:                                               String def)
 309:   {
 310:     ResourceBundle res;
 311:     try
 312:       {
 313:     res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
 314:         loc, ClassLoader.getSystemClassLoader());
 315:       }
 316:     catch (MissingResourceException x)
 317:       {
 318:     res = null;
 319:       }
 320:     String fmt;
 321:     try
 322:       {
 323:     fmt = res == null ? def : res.getString(resource);
 324:       }
 325:     catch (MissingResourceException x)
 326:       {
 327:     fmt = def;
 328:       }
 329:     DecimalFormatSymbols dfs = new DecimalFormatSymbols (loc);
 330:     return new DecimalFormat (fmt, dfs);
 331:   }
 332: 
 333:   /**
 334:    * This method returns an instance of <code>NumberFormat</code> suitable
 335:    * for formatting and parsing currency values in the default locale.
 336:    *
 337:    * @return An instance of <code>NumberFormat</code> for handling currencies.
 338:    */
 339:   public static final NumberFormat getCurrencyInstance ()
 340:   {
 341:     return getCurrencyInstance (Locale.getDefault());
 342:   }
 343: 
 344:   /**
 345:    * This method returns an instance of <code>NumberFormat</code> suitable
 346:    * for formatting and parsing currency values in the specified locale.
 347:    *
 348:    * @return An instance of <code>NumberFormat</code> for handling currencies.
 349:    */
 350:   public static NumberFormat getCurrencyInstance (Locale loc)
 351:   {
 352:     NumberFormat format;
 353:     
 354:     format = computeInstance (loc, "currencyFormat", "$#,##0.00;($#,##0.00)");
 355:     format.setMaximumFractionDigits(format.getCurrency().getDefaultFractionDigits());  
 356:     return format;
 357:   }
 358: 
 359:   /**
 360:    * This method returns a default instance for the default locale. This
 361:    * will be a concrete subclass of <code>NumberFormat</code>, but the 
 362:    * actual class returned is dependent on the locale.
 363:    *
 364:    * @return An instance of the default <code>NumberFormat</code> class.
 365:    */
 366:   public static final NumberFormat getInstance ()
 367:   {
 368:     return getInstance (Locale.getDefault());
 369:   }
 370: 
 371:   /**
 372:    * This method returns a default instance for the specified locale. This
 373:    * will be a concrete subclass of <code>NumberFormat</code>, but the 
 374:    * actual class returned is dependent on the locale.
 375:    *
 376:    * @param loc The desired locale.
 377:    *
 378:    * @return An instance of the default <code>NumberFormat</code> class.
 379:    */
 380:   public static NumberFormat getInstance (Locale loc)
 381:   {
 382:     // For now always return a number instance.
 383:     return getNumberInstance (loc);
 384:   }
 385: 
 386:   /**
 387:    * This method returns the maximum number of digits allowed in the fraction
 388:    * portion of a number.
 389:    *
 390:    * @return The maximum number of digits allowed in the fraction
 391:    * portion of a number. 
 392:    */
 393:   public int getMaximumFractionDigits ()
 394:   {
 395:     return maximumFractionDigits;
 396:   }
 397: 
 398:   /**
 399:    * This method returns the maximum number of digits allowed in the integer
 400:    * portion of a number.
 401:    *
 402:    * @return The maximum number of digits allowed in the integer
 403:    * portion of a number. 
 404:    */
 405:   public int getMaximumIntegerDigits ()
 406:   {
 407:     return maximumIntegerDigits;
 408:   }
 409: 
 410:   /**
 411:    * This method returns the minimum number of digits allowed in the fraction
 412:    * portion of a number.
 413:    *
 414:    * @return The minimum number of digits allowed in the fraction
 415:    * portion of a number. 
 416:    */
 417:   public int getMinimumFractionDigits ()
 418:   {
 419:     return minimumFractionDigits;
 420:   }
 421: 
 422:   /**
 423:    * This method returns the minimum number of digits allowed in the integer
 424:    * portion of a number.
 425:    *
 426:    * @return The minimum number of digits allowed in the integer
 427:    * portion of a number. 
 428:    */
 429:   public int getMinimumIntegerDigits ()
 430:   {
 431:     return minimumIntegerDigits;
 432:   }
 433: 
 434:   /**
 435:    * This method returns a default instance for the specified locale. This
 436:    * will be a concrete subclass of <code>NumberFormat</code>, but the 
 437:    * actual class returned is dependent on the locale.
 438:    *
 439:    * @return An instance of the default <code>NumberFormat</code> class.
 440:    */
 441:   public static final NumberFormat getNumberInstance ()
 442:   {
 443:     return getNumberInstance (Locale.getDefault());
 444:   }
 445: 
 446:   /**
 447:    * This method returns a general purpose number formatting and parsing
 448:    * class for the default locale.  This will be a concrete subclass of
 449:    * <code>NumberFormat</code>, but the actual class returned is dependent
 450:    * on the locale.
 451:    *
 452:    * @return An instance of a generic number formatter for the default locale.
 453:    */
 454:   public static NumberFormat getNumberInstance (Locale loc)
 455:   {
 456:     return computeInstance (loc, "numberFormat", "#,##0.###");
 457:   }
 458: 
 459:   /**
 460:    * This method returns an integer formatting and parsing class for the
 461:    * default locale. This will be a concrete subclass of <code>NumberFormat</code>,
 462:    * but the actual class returned is dependent on the locale.
 463:    *
 464:    * @return An instance of an integer number formatter for the default locale.
 465:    * @since 1.4 
 466:    */
 467:   public static final NumberFormat getIntegerInstance()
 468:   {
 469:     return getIntegerInstance (Locale.getDefault());
 470:   }
 471: 
 472:   /**
 473:    * This method returns an integer formatting and parsing class for the
 474:    * default locale. This will be a concrete subclass of <code>NumberFormat</code>,
 475:    * but the actual class returned is dependent on the locale.
 476:    *
 477:    * @param locale the desired locale.
 478:    *
 479:    * @return An instance of an integer number formatter for the desired locale.
 480:    * @since 1.4 
 481:    */
 482:   public static NumberFormat getIntegerInstance(Locale locale)
 483:   {
 484:     NumberFormat format = computeInstance (locale, "numberFormat", "#,##0");
 485:     format.setMaximumFractionDigits(0);
 486:     format.setParseIntegerOnly (true);
 487:     return format;
 488:   }
 489: 
 490:   /**
 491:    * This method returns an instance of <code>NumberFormat</code> suitable
 492:    * for formatting and parsing percentage values in the default locale.
 493:    *
 494:    * @return An instance of <code>NumberFormat</code> for handling percentages.
 495:    */
 496:   public static final NumberFormat getPercentInstance ()
 497:   {
 498:     return getPercentInstance (Locale.getDefault());
 499:   }
 500: 
 501:   /**
 502:    * This method returns an instance of <code>NumberFormat</code> suitable
 503:    * for formatting and parsing percentage values in the specified locale.
 504:    *
 505:    * @param loc The desired locale.
 506:    *
 507:    * @return An instance of <code>NumberFormat</code> for handling percentages.
 508:    */
 509:   public static NumberFormat getPercentInstance (Locale loc)
 510:   {
 511:     return computeInstance (loc, "percentFormat", "#,##0%");
 512:   }
 513: 
 514:   /**
 515:    * This method returns a hash value for this object.
 516:    *
 517:    * @return The hash code.
 518:    */
 519:   public int hashCode ()
 520:   {
 521:     int hash = super.hashCode();
 522:     hash ^= (maximumFractionDigits + maximumIntegerDigits
 523:          + minimumFractionDigits + minimumIntegerDigits);
 524:     if (groupingUsed)
 525:       hash ^= 0xf0f0;
 526:     if (parseIntegerOnly)
 527:       hash ^= 0x0f0f;
 528:     return hash;
 529:   }
 530: 
 531:   /**
 532:    * This method tests whether or not grouping is in use.  Grouping is
 533:    * a method of marking separations in numbers, such as thousand separators
 534:    * in the US English locale.  The grouping positions and symbols are all
 535:    * locale specific.  As an example, with grouping disabled, the number one
 536:    * million would appear as "1000000".  With grouping enabled, this number
 537:    * might appear as "1,000,000".  (Both of these assume the US English
 538:    * locale).
 539:    *
 540:    * @return <code>true</code> if grouping is enabled,
 541:    * <code>false</code> otherwise. 
 542:    */
 543:   public boolean isGroupingUsed ()
 544:   {
 545:     return groupingUsed;
 546:   }
 547: 
 548:   /**
 549:    * This method tests whether or not only integer values should be parsed.
 550:    * If this class is parsing only integers, parsing stops at the decimal
 551:    * point.
 552:    *
 553:    * @return <code>true</code> if only integers are parsed,
 554:    * <code>false</code> otherwise. 
 555:    */
 556:   public boolean isParseIntegerOnly ()
 557:   {
 558:     return parseIntegerOnly;
 559:   }
 560: 
 561:   /**
 562:    * This is a default constructor for use by subclasses.
 563:    */
 564:   public NumberFormat ()
 565:   {
 566:   }
 567: 
 568:   /**
 569:    * This method parses the specified string into a <code>Number</code>.  This
 570:    * will be a <code>Long</code> if possible, otherwise it will be a
 571:    * <code>Double</code>.    If no number can be parsed, no exception is
 572:    * thrown.  Instead, the parse position remains at its initial index.
 573:    *
 574:    * @param sourceStr The string to parse.
 575:    * @param pos The desired <code>ParsePosition</code>.
 576:    *
 577:    * @return The parsed <code>Number</code>
 578:    */
 579:   public abstract Number parse (String sourceStr, ParsePosition pos);
 580: 
 581:   /**
 582:    * This method parses the specified string into a <code>Number</code>.  This
 583:    * will be a <code>Long</code> if possible, otherwise it will be a
 584:    * <code>Double</code>.  If no number can be parsed, an exception will be
 585:    * thrown.
 586:    *
 587:    * @param sourceStr The string to parse.
 588:    *
 589:    * @return The parsed <code>Number</code>
 590:    *
 591:    * @exception ParseException If no number can be parsed.
 592:    */
 593:   public Number parse (String sourceStr) throws ParseException
 594:   {
 595:     ParsePosition pp = new ParsePosition (0);
 596:     Number r = parse (sourceStr, pp);
 597:     if (r == null)
 598:       {
 599:     int index = pp.getErrorIndex();
 600:     if (index < 0)
 601:       index = pp.getIndex();
 602:     throw new ParseException ("couldn't parse number", index);
 603:       }
 604:     return r;
 605:   }
 606: 
 607:   /**
 608:    * This method parses the specified string into an <code>Object</code>.  This
 609:    * will be a <code>Long</code> if possible, otherwise it will be a
 610:    * <code>Double</code>.    If no number can be parsed, no exception is
 611:    * thrown.  Instead, the parse position remains at its initial index.
 612:    *
 613:    * @param sourceStr The string to parse.
 614:    * @param pos The desired <code>ParsePosition</code>.
 615:   *
 616:   * @return The parsed <code>Object</code>
 617:   */
 618:   public final Object parseObject (String sourceStr, ParsePosition pos)
 619:   {
 620:     return parse (sourceStr, pos);
 621:   }
 622: 
 623:   /**
 624:    * This method sets the grouping behavior of this formatter.  Grouping is
 625:    * a method of marking separations in numbers, such as thousand separators
 626:    * in the US English locale.  The grouping positions and symbols are all
 627:    * locale specific.  As an example, with grouping disabled, the number one
 628:    * million would appear as "1000000".  With grouping enabled, this number
 629:    * might appear as "1,000,000".  (Both of these assume the US English
 630:    * locale).
 631:    *
 632:    * @param newValue <code>true</code> to enable grouping,
 633:    *                     <code>false</code> to disable it. 
 634:    */
 635:   public void setGroupingUsed (boolean newValue)
 636:   {
 637:     groupingUsed = newValue;
 638:   }
 639: 
 640:   /**
 641:    * This method sets the maximum number of digits allowed in the fraction
 642:    * portion of a number to the specified value.  If this is less than the
 643:    * current minimum allowed digits, the minimum allowed digits value will
 644:    * be lowered to be equal to the new maximum allowed digits value.
 645:    *
 646:    * @param digits The new maximum fraction digits value.
 647:    */
 648:   public void setMaximumFractionDigits (int digits)
 649:   {
 650:     maximumFractionDigits = digits;
 651:     if (getMinimumFractionDigits () > maximumFractionDigits)
 652:       setMinimumFractionDigits (maximumFractionDigits);
 653:   }
 654: 
 655:   /**
 656:    * This method sets the maximum number of digits allowed in the integer
 657:    * portion of a number to the specified value.  If this is less than the
 658:    * current minimum allowed digits, the minimum allowed digits value will
 659:    * be lowered to be equal to the new maximum allowed digits value.
 660:    *
 661:    * @param digits The new maximum integer digits value.
 662:    */
 663:   public void setMaximumIntegerDigits (int digits)
 664:   {
 665:     maximumIntegerDigits = digits;
 666:     if (getMinimumIntegerDigits () > maximumIntegerDigits)
 667:       setMinimumIntegerDigits (maximumIntegerDigits);
 668:   }
 669: 
 670:   /**
 671:    * This method sets the minimum number of digits allowed in the fraction
 672:    * portion of a number to the specified value.  If this is greater than the
 673:    * current maximum allowed digits, the maximum allowed digits value will
 674:    * be raised to be equal to the new minimum allowed digits value.
 675:    *
 676:    * @param digits The new minimum fraction digits value.
 677:    */
 678:   public void setMinimumFractionDigits (int digits)
 679:   {
 680:     minimumFractionDigits = digits;
 681:     if (getMaximumFractionDigits () < minimumFractionDigits)
 682:       setMaximumFractionDigits (minimumFractionDigits);
 683:   }
 684: 
 685:   /**
 686:    * This method sets the minimum number of digits allowed in the integer
 687:    * portion of a number to the specified value.  If this is greater than the
 688:    * current maximum allowed digits, the maximum allowed digits value will
 689:    * be raised to be equal to the new minimum allowed digits value.
 690:    *
 691:    * @param digits The new minimum integer digits value.
 692:    */
 693:   public void setMinimumIntegerDigits (int digits)
 694:   {
 695:     minimumIntegerDigits = digits;
 696:     if (getMaximumIntegerDigits () < minimumIntegerDigits)
 697:       setMaximumIntegerDigits (minimumIntegerDigits);
 698:   }
 699: 
 700:   /** 
 701:    * This method sets the parsing behavior of this object to parse only 
 702:    * integers or not.
 703:    *
 704:    * @param value <code>true</code> to parse only integers,
 705:    *                         <code>false</code> otherwise. 
 706:    */
 707:   public void setParseIntegerOnly (boolean value)
 708:   {
 709:     parseIntegerOnly = value;
 710:   }
 711: 
 712:   /**
 713:    * This method is a specialization of the format method that performs
 714:    * a simple formatting of the specified <code>double</code> number.
 715:    *
 716:    * @param number The <code>double</code> to format.
 717:    *
 718:    * @return The formatted number
 719:    */
 720:   public final String format (double number)
 721:   {
 722:     StringBuffer sbuf = new StringBuffer(50);
 723:     format (number, sbuf, null);
 724:     return sbuf.toString();
 725:   }
 726: 
 727:   // These field names are fixed by the serialization spec.
 728:   boolean groupingUsed;
 729:   int maximumFractionDigits;
 730:   private byte maxFractionDigits;
 731:   int maximumIntegerDigits;
 732:   private byte maxIntegerDigits;
 733:   int minimumFractionDigits;
 734:   private byte minFractionDigits;
 735:   int minimumIntegerDigits;
 736:   private byte minIntegerDigits;
 737:   boolean parseIntegerOnly;
 738:   private int serialVersionOnStream;
 739:   private static final long serialVersionUID = -2308460125733713944L;
 740: 
 741:   private void readObject(ObjectInputStream stream)
 742:     throws IOException, ClassNotFoundException
 743:   {
 744:     stream.defaultReadObject();
 745:     if (serialVersionOnStream < 1)
 746:       {
 747:         maximumFractionDigits = maxFractionDigits;
 748:     maximumIntegerDigits = maxIntegerDigits;
 749:     minimumFractionDigits = minFractionDigits;
 750:     minimumIntegerDigits = minIntegerDigits;
 751:     serialVersionOnStream = 1;
 752:       }
 753:   }
 754: 
 755:   private void writeObject(ObjectOutputStream stream) throws IOException
 756:   {
 757:     maxFractionDigits = maximumFractionDigits < Byte.MAX_VALUE ?
 758:       (byte) maximumFractionDigits : Byte.MAX_VALUE;
 759:     maxIntegerDigits = maximumIntegerDigits < Byte.MAX_VALUE ?
 760:       (byte) maximumIntegerDigits : Byte.MAX_VALUE;
 761:     minFractionDigits = minimumFractionDigits < Byte.MAX_VALUE ?
 762:       (byte) minimumFractionDigits : Byte.MAX_VALUE;
 763:     minIntegerDigits = minimumIntegerDigits < Byte.MAX_VALUE ?
 764:       (byte) minimumIntegerDigits : Byte.MAX_VALUE;
 765:     serialVersionOnStream = 1;
 766:     stream.defaultWriteObject();
 767:   }
 768: 
 769:   /**
 770:    * Returns the currency used by this number format when formatting currency
 771:    * values.
 772:    *
 773:    * The default implementation throws UnsupportedOperationException.
 774:    *
 775:    * @return The used currency object, or null.
 776:    *
 777:    * @throws UnsupportedOperationException If the number format class doesn't
 778:    * implement currency formatting.
 779:    *
 780:    * @since 1.4
 781:    */
 782:   public Currency getCurrency()
 783:   {
 784:     throw new UnsupportedOperationException();
 785:   }
 786: 
 787:   /**
 788:    * Sets the currency used by this number format when formatting currency
 789:    * values.
 790:    *
 791:    * The default implementation throws UnsupportedOperationException.
 792:    *
 793:    * @param currency The new currency to be used by this number format.
 794:    *
 795:    * @throws NullPointerException If currenc is null.
 796:    * @throws UnsupportedOperationException If the number format class doesn't
 797:    * implement currency formatting.
 798:    *
 799:    * @since 1.4
 800:    */
 801:   public void setCurrency(Currency currency)
 802:   {
 803:     if (currency == null)
 804:       throw new NullPointerException("currency may not be null");
 805:     
 806:     throw new UnsupportedOperationException();
 807:   }
 808: }