]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.datatypes/src/org/simantics/datatypes/literal/DecimalFormatFormatter.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.datatypes / src / org / simantics / datatypes / literal / DecimalFormatFormatter.java
1 package org.simantics.datatypes.literal;\r
2 \r
3 import java.text.DecimalFormat;\r
4 import java.text.DecimalFormatSymbols;\r
5 import java.util.Locale;\r
6 \r
7 import org.simantics.common.format.Formatter;\r
8 import org.simantics.databoard.Bindings;\r
9 import org.simantics.databoard.binding.Binding;\r
10 import org.simantics.databoard.util.Bean;\r
11 \r
12 \r
13 public class DecimalFormatFormatter extends Bean implements Formatter {\r
14 \r
15         public static final Binding BINDING = Bindings.getBindingUnchecked(DecimalFormatFormatter.class);\r
16 \r
17         public String formatString;\r
18 \r
19         private volatile DecimalFormat format;\r
20 \r
21         public DecimalFormatFormatter() {\r
22                 this("0.###############");\r
23         }\r
24 \r
25         public DecimalFormatFormatter(String formatString) {\r
26                 if (formatString == null)\r
27                         throw new NullPointerException("null formatString");\r
28                 this.formatString = formatString;\r
29         }\r
30         \r
31         public DecimalFormat getFormat() {\r
32                 if(format == null) {\r
33                         format = new java.text.DecimalFormat(formatString, DecimalFormatSymbols.getInstance(Locale.US));\r
34                 }\r
35                 return format;\r
36         }\r
37 \r
38         @Override\r
39         public String format(Object object) {\r
40                 if (object instanceof String) return object.toString();\r
41                 else if (object instanceof Number) {\r
42 \r
43                         DecimalFormat format = getFormat();\r
44 //                      System.out.println("formatString: " + formatString);\r
45                         int integers = format.getMaximumIntegerDigits();\r
46                         //System.out.println("  integers: " + integers);\r
47                         if (integers == Integer.MAX_VALUE) {\r
48                                 // Parse number of integer digits from format string.\r
49                                 integers = countIntegerDigits(formatString);\r
50                         }\r
51                         //System.out.println("  decimals: " + format.getMaximumFractionDigits());\r
52                         //System.out.println("  integers: " + format.getMinimumIntegerDigits());\r
53                         //System.out.println("  decimals: " + format.getMinimumFractionDigits());\r
54                         String result = format.format(object);\r
55                         //System.out.println("result: " + result);\r
56                         int resultIntegers = countResultDigits(result);\r
57                         //System.out.println("  result integers: " + resultIntegers);\r
58                         if (resultIntegers > integers) {\r
59                                 // Guard against format.getMaximumFractionDigits returning Integer.MAX_VALUE\r
60                                 int decimals = Math.min(format.getMaximumFractionDigits(), 15);\r
61                                 return getLimitString(integers, decimals);\r
62                         }\r
63                         return result; \r
64                 } else {\r
65                         return object != null ? object.toString() : "";\r
66                 }\r
67         }       \r
68         \r
69         private int countIntegerDigits(String formatString) {\r
70                 int digits = 0;\r
71                 int len = formatString.length();\r
72                 boolean escape = false;\r
73                 for (int i = 0; i < len; ++i) {\r
74                         char ch = formatString.charAt(i);\r
75                         if (ch == '.')\r
76                                 break;\r
77                         else if (ch == '\'')\r
78                                 escape = true;\r
79                         else if (!escape && (ch == '#' || ch == '0'))\r
80                                 ++digits;\r
81                 }\r
82                 return digits;\r
83         }\r
84 \r
85         private int countResultDigits(String formattedString) {\r
86                 int digits = 0;\r
87                 int len = formattedString.length();\r
88                 for (int i = 0; i < len; ++i) {\r
89                         char ch = formattedString.charAt(i);\r
90                         if (ch == '.')\r
91                                 break;\r
92                         else if (Character.isDigit(ch))\r
93                                 ++digits;\r
94                 }\r
95                 return digits;\r
96         }\r
97         \r
98         private String getLimitString(int integers, int decimals) {\r
99                 StringBuilder b = new StringBuilder(integers + decimals + 1);\r
100                 for(int i=0;i<integers;i++) b.append('*');\r
101                 b.append('.');\r
102                 for(int i=0;i<decimals;i++) b.append('*');\r
103                 return b.toString();\r
104         }\r
105         \r
106 }\r