]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils/src/org/simantics/utils/format/FormattingUtils.java
Allow specification of Locale to FormattingUtils.significantDigitFormat
[simantics/platform.git] / bundles / org.simantics.utils / src / org / simantics / utils / format / FormattingUtils.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.utils.format;
13
14 import java.math.BigDecimal;
15 import java.math.MathContext;
16 import java.text.DecimalFormat;
17 import java.text.DecimalFormatSymbols;
18 import java.text.FieldPosition;
19 import java.text.Format;
20 import java.text.NumberFormat;
21 import java.text.ParsePosition;
22 import java.util.Locale;
23
24 /**
25  * @author Antti Villberg
26  */
27 public class FormattingUtils {
28
29     public static final FormattingUtil US      = new FormattingUtil(5, 5, Locale.US);
30     public static final FormattingUtil DEFAULT = US;
31
32     public static String engineeringFormat(Object value) {
33         return DEFAULT.engineeringFormat(value);
34     }
35
36     public static Format significantDigitFormat(int withSignificantDigits) {
37         return significantDigitFormat(Locale.getDefault(Locale.Category.FORMAT), withSignificantDigits);
38     }
39
40     public static Format significantDigitFormat(Locale locale, int withSignificantDigits) {
41         return significantDigitFormat(locale, withSignificantDigits, false);
42     }
43
44     public static Format significantDigitFormat(int withSignificantDigits, boolean stripTrailingZeros) {
45         return significantDigitFormat(Locale.getDefault(Locale.Category.FORMAT), withSignificantDigits, stripTrailingZeros);
46     }
47
48     public static Format significantDigitFormat(Locale locale, int withSignificantDigits, boolean stripTrailingZeros) {
49         if (withSignificantDigits < 1)
50             throw new IllegalArgumentException("withSignificantDigits must be > 0, got " + withSignificantDigits);
51         StringBuilder sb = new StringBuilder(withSignificantDigits + 3);
52         sb.append("0.");
53         for (int i = 0; i < withSignificantDigits-1; i++)
54             sb.append("#");
55         sb.append("E0");
56         NumberFormat low = new DecimalFormat(sb.toString(), DecimalFormatSymbols.getInstance(locale));
57         low.setGroupingUsed(false);
58         NumberFormat hi = new SignificantDigitFormat(locale, withSignificantDigits, stripTrailingZeros);
59         Format format = new SwitchFormat(0.1, 1, low, hi, hi);
60         return format;
61     }
62
63     private static class SignificantDigitFormat extends NumberFormat {
64
65         private static final long serialVersionUID = 1079268918077141671L;
66
67         private MathContext mc;
68         private boolean stripTrailingZeros;
69         private boolean fixDecimalSeparator;
70         private char decimalSeparator;
71
72         public SignificantDigitFormat(Locale locale, int digits, boolean stripTrailingZeros) {
73             this.mc = new MathContext(digits);
74             this.stripTrailingZeros = stripTrailingZeros;
75             DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locale);
76             decimalSeparator = symbols.getDecimalSeparator();
77             // BigDecimal always formats doubles with '.' as decimal separator.
78             if (decimalSeparator != '.')
79                 fixDecimalSeparator = true;
80             else
81                 fixDecimalSeparator = false;
82         }
83
84         @Override
85         public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
86             BigDecimal big = new BigDecimal(number, mc);
87             if (stripTrailingZeros)
88                 big = big.stripTrailingZeros();
89             String str = big.toString();
90             if (fixDecimalSeparator)
91                 str = str.replace('.', decimalSeparator);
92             return toAppendTo.append(str);
93         }
94
95         @Override
96         public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
97             return toAppendTo.append(number);
98         }
99
100         @Override
101         public Number parse(String source, ParsePosition parsePosition) {
102             return 0;
103         }
104
105     }
106
107 }