1 16 17 package org.apache.commons.math.fraction; 18 19 import java.io.Serializable ; 20 import java.text.FieldPosition ; 21 import java.text.Format ; 22 import java.text.NumberFormat ; 23 import java.text.ParseException ; 24 import java.text.ParsePosition ; 25 import java.util.Locale ; 26 27 import org.apache.commons.math.ConvergenceException; 28 29 37 public class FractionFormat extends Format implements Serializable { 38 39 40 static final long serialVersionUID = -6337346779577272306L; 41 42 43 private NumberFormat denominatorFormat; 44 45 46 private NumberFormat numeratorFormat; 47 48 52 public FractionFormat() { 53 this(getDefaultNumberFormat()); 54 } 55 56 61 public FractionFormat(NumberFormat format) { 62 this(format, (NumberFormat )format.clone()); 63 } 64 65 71 public FractionFormat(NumberFormat numeratorFormat, 72 NumberFormat denominatorFormat) 73 { 74 super(); 75 this.numeratorFormat = numeratorFormat; 76 this.denominatorFormat = denominatorFormat; 77 } 78 79 86 public static String formatFraction(Fraction f) { 87 return getImproperInstance().format(f); 88 } 89 90 95 public static Locale [] getAvailableLocales() { 96 return NumberFormat.getAvailableLocales(); 97 } 98 99 103 public static FractionFormat getImproperInstance() { 104 return getImproperInstance(Locale.getDefault()); 105 } 106 107 112 public static FractionFormat getImproperInstance(Locale locale) { 113 NumberFormat f = getDefaultNumberFormat(locale); 114 return new FractionFormat(f); 115 } 116 117 121 public static FractionFormat getProperInstance() { 122 return getProperInstance(Locale.getDefault()); 123 } 124 125 130 public static FractionFormat getProperInstance(Locale locale) { 131 NumberFormat f = getDefaultNumberFormat(locale); 132 return new ProperFractionFormat(f); 133 } 134 135 141 protected static NumberFormat getDefaultNumberFormat() { 142 return getDefaultNumberFormat(Locale.getDefault()); 143 } 144 145 152 private static NumberFormat getDefaultNumberFormat(Locale locale) { 153 NumberFormat nf = NumberFormat.getNumberInstance(locale); 154 nf.setMaximumFractionDigits(0); 155 nf.setParseIntegerOnly(true); 156 return nf; 157 } 158 159 169 public StringBuffer format(Fraction fraction, StringBuffer toAppendTo, 170 FieldPosition pos) { 171 172 pos.setBeginIndex(0); 173 pos.setEndIndex(0); 174 175 getNumeratorFormat().format(fraction.getNumerator(), toAppendTo, pos); 176 toAppendTo.append(" / "); 177 getDenominatorFormat().format(fraction.getDenominator(), toAppendTo, 178 pos); 179 180 return toAppendTo; 181 } 182 183 196 public StringBuffer format(Object obj, StringBuffer toAppendTo, 197 FieldPosition pos) 198 { 199 StringBuffer ret = null; 200 201 if (obj instanceof Fraction) { 202 ret = format( (Fraction)obj, toAppendTo, pos); 203 } else if (obj instanceof Number ) { 204 try { 205 ret = format( new Fraction(((Number )obj).doubleValue()), 206 toAppendTo, pos); 207 } catch (ConvergenceException ex) { 208 throw new IllegalArgumentException ( 209 "Cannot convert given object to a fraction."); 210 } 211 } else { 212 throw new IllegalArgumentException ( 213 "Cannot format given object as a fraction"); 214 } 215 216 return ret; 217 } 218 219 223 public NumberFormat getDenominatorFormat() { 224 return denominatorFormat; 225 } 226 227 231 public NumberFormat getNumeratorFormat() { 232 return numeratorFormat; 233 } 234 235 242 public Fraction parse(String source) throws ParseException { 243 ParsePosition parsePosition = new ParsePosition (0); 244 Fraction result = parse(source, parsePosition); 245 if (parsePosition.getIndex() == 0) { 246 throw new ParseException ("Unparseable fraction number: \"" + 247 source + "\"", parsePosition.getErrorIndex()); 248 } 249 return result; 250 } 251 252 259 public Fraction parse(String source, ParsePosition pos) { 260 int initialIndex = pos.getIndex(); 261 262 parseAndIgnoreWhitespace(source, pos); 264 265 Number num = getNumeratorFormat().parse(source, pos); 267 if (num == null) { 268 pos.setIndex(initialIndex); 272 return null; 273 } 274 275 int startIndex = pos.getIndex(); 277 char c = parseNextCharacter(source, pos); 278 switch (c) { 279 case 0 : 280 return new Fraction(num.intValue(), 1); 283 case '/' : 284 break; 286 default : 287 pos.setIndex(initialIndex); 291 pos.setErrorIndex(startIndex); 292 return null; 293 } 294 295 parseAndIgnoreWhitespace(source, pos); 297 298 Number den = getDenominatorFormat().parse(source, pos); 300 if (den == null) { 301 pos.setIndex(initialIndex); 305 return null; 306 } 307 308 return new Fraction(num.intValue(), den.intValue()); 309 } 310 311 318 public Object parseObject(String source, ParsePosition pos) { 319 return parse(source, pos); 320 } 321 322 328 public void setDenominatorFormat(NumberFormat format) { 329 if (format == null) { 330 throw new IllegalArgumentException ( 331 "denominator format can not be null."); 332 } 333 this.denominatorFormat = format; 334 } 335 336 342 public void setNumeratorFormat(NumberFormat format) { 343 if (format == null) { 344 throw new IllegalArgumentException ( 345 "numerator format can not be null."); 346 } 347 this.numeratorFormat = format; 348 } 349 350 356 protected static void parseAndIgnoreWhitespace( 357 String source, ParsePosition pos) 358 { 359 parseNextCharacter(source, pos); 360 pos.setIndex(pos.getIndex() - 1); 361 } 362 363 369 protected static char parseNextCharacter(String source, ParsePosition pos) { 370 int index = pos.getIndex(); 371 int n = source.length(); 372 char ret = 0; 373 374 if (index < n) { 375 char c; 376 do { 377 c = source.charAt(index++); 378 } while (Character.isWhitespace(c) && index < n); 379 pos.setIndex(index); 380 381 if (index < n) { 382 ret = c; 383 } 384 } 385 386 return ret; 387 } 388 } 389 | Popular Tags |