--- /dev/null
+package org.simantics.datatypes.literal;\r
+\r
+import java.text.DecimalFormat;\r
+import java.text.DecimalFormatSymbols;\r
+import java.util.Locale;\r
+\r
+import org.simantics.common.format.Formatter;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.util.Bean;\r
+\r
+\r
+public class DecimalFormatFormatter extends Bean implements Formatter {\r
+\r
+ public static final Binding BINDING = Bindings.getBindingUnchecked(DecimalFormatFormatter.class);\r
+\r
+ public String formatString;\r
+\r
+ private volatile DecimalFormat format;\r
+\r
+ public DecimalFormatFormatter() {\r
+ this("0.###############");\r
+ }\r
+\r
+ public DecimalFormatFormatter(String formatString) {\r
+ if (formatString == null)\r
+ throw new NullPointerException("null formatString");\r
+ this.formatString = formatString;\r
+ }\r
+ \r
+ public DecimalFormat getFormat() {\r
+ if(format == null) {\r
+ format = new java.text.DecimalFormat(formatString, DecimalFormatSymbols.getInstance(Locale.US));\r
+ }\r
+ return format;\r
+ }\r
+\r
+ @Override\r
+ public String format(Object object) {\r
+ if (object instanceof String) return object.toString();\r
+ else if (object instanceof Number) {\r
+\r
+ DecimalFormat format = getFormat();\r
+// System.out.println("formatString: " + formatString);\r
+ int integers = format.getMaximumIntegerDigits();\r
+ //System.out.println(" integers: " + integers);\r
+ if (integers == Integer.MAX_VALUE) {\r
+ // Parse number of integer digits from format string.\r
+ integers = countIntegerDigits(formatString);\r
+ }\r
+ //System.out.println(" decimals: " + format.getMaximumFractionDigits());\r
+ //System.out.println(" integers: " + format.getMinimumIntegerDigits());\r
+ //System.out.println(" decimals: " + format.getMinimumFractionDigits());\r
+ String result = format.format(object);\r
+ //System.out.println("result: " + result);\r
+ int resultIntegers = countResultDigits(result);\r
+ //System.out.println(" result integers: " + resultIntegers);\r
+ if (resultIntegers > integers) {\r
+ // Guard against format.getMaximumFractionDigits returning Integer.MAX_VALUE\r
+ int decimals = Math.min(format.getMaximumFractionDigits(), 15);\r
+ return getLimitString(integers, decimals);\r
+ }\r
+ return result; \r
+ } else {\r
+ return object != null ? object.toString() : "";\r
+ }\r
+ } \r
+ \r
+ private int countIntegerDigits(String formatString) {\r
+ int digits = 0;\r
+ int len = formatString.length();\r
+ boolean escape = false;\r
+ for (int i = 0; i < len; ++i) {\r
+ char ch = formatString.charAt(i);\r
+ if (ch == '.')\r
+ break;\r
+ else if (ch == '\'')\r
+ escape = true;\r
+ else if (!escape && (ch == '#' || ch == '0'))\r
+ ++digits;\r
+ }\r
+ return digits;\r
+ }\r
+\r
+ private int countResultDigits(String formattedString) {\r
+ int digits = 0;\r
+ int len = formattedString.length();\r
+ for (int i = 0; i < len; ++i) {\r
+ char ch = formattedString.charAt(i);\r
+ if (ch == '.')\r
+ break;\r
+ else if (Character.isDigit(ch))\r
+ ++digits;\r
+ }\r
+ return digits;\r
+ }\r
+ \r
+ private String getLimitString(int integers, int decimals) {\r
+ StringBuilder b = new StringBuilder(integers + decimals + 1);\r
+ for(int i=0;i<integers;i++) b.append('*');\r
+ b.append('.');\r
+ for(int i=0;i<decimals;i++) b.append('*');\r
+ return b.toString();\r
+ }\r
+ \r
+}\r