2

In my GWT web application I have a textbox that holds a price. How can one convert that String to a BigDecimal?

kroiz
  • 1,722
  • 1
  • 27
  • 43
  • I am not familiar with gwt but in Java you just write: `BigDecimal bd = new BigDecimal(yourString);`. – assylias May 02 '12 at 12:24
  • possible duplicate of [Safe String to BigDecimal conversion](http://stackoverflow.com/questions/3752578/safe-string-to-bigdecimal-conversion) – Kai May 02 '12 at 12:26
  • I think you need to use the the function DecimalFormat.setParseBigDecimal but you cannot in GWT – kroiz May 02 '12 at 12:30
  • 3
    Not a duplication cause you cannot do it in GWT. – kroiz May 02 '12 at 12:33

2 Answers2

9

The easiest way is to create new text box widget that inherits ValueBox. If you do it this way, you won't have to convert any string values manually. the ValueBox takes care of it all.

To get the BigDecimal value entered you can just go:

BigDecimal value = myTextBox.getValue();

Your BigDecimalBox.java:

public class BigDecimalBox extends ValueBox<BigDecimal> {
  public BigDecimalBox() {
    super(Document.get().createTextInputElement(), BigDecimalRenderer.instance(),
        BigDecimalParser.instance());
  }
}

Then your BigDecimalRenderer.java

public class BigDecimalRenderer extends AbstractRenderer<BigDecimal> {
  private static BigDecimalRenderer INSTANCE;

  public static Renderer<BigDecimal> instance() {
    if (INSTANCE == null) {
      INSTANCE = new BigDecimalRenderer();
    }
    return INSTANCE;
  }

  protected BigDecimalRenderer() {
  }

  public String render(BigDecimal object) {
    if (null == object) {
      return "";
    }

    return NumberFormat.getDecimalFormat().format(object);
  }
}

And your BigDecimalParser.java

package com.google.gwt.text.client;

import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.text.shared.Parser;

import java.text.ParseException;

public class BigDecimalParser implements Parser<BigDecimal> {

  private static BigDecimalParser INSTANCE;

  public static Parser<BigDecimal> instance() {
    if (INSTANCE == null) {
      INSTANCE = new BigDecimalParser();
    }
    return INSTANCE;
  }

  protected BigDecimalParser() {
  }

  public BigDecimal parse(CharSequence object) throws ParseException {
    if ("".equals(object.toString())) {
      return null;
    }

    try {
      return new BigDecimal(object.toString());
    } catch (NumberFormatException e) {
      throw new ParseException(e.getMessage(), 0);
    }
  }
}
Strelok
  • 50,229
  • 9
  • 102
  • 115
  • 1
    I tried this method - it sort of works. The issue is that `getDecimalFormat()` returns a `NumberFormat` that includes thousands separators. Whereas `new BigDecimal` does not parse thousands separators. There doesn't seem to be simple workaround, without parsing to `double` and rounding appropriately. – Boris the Spider Feb 16 '16 at 15:54
  • @Boris the Spider, you can certainly use a custom NumberFormat that doesn't output thousands separators or strip the separators out of the string prior to parsing or use NumberFormat to parse a BigDecimal (by .setParseBigDecimal(true). See this question: http://stackoverflow.com/questions/14346403/how-to-parse-a-string-number-into-a-bigdecimal – Strelok Feb 16 '16 at 23:47
  • 1
    The first option kind of defeats the purpose of `NumberFormat` - at that point `BigDecimal.toPlainString` does the job. The second option brings in all sorts of locale problems - certainly doable, but seems like reinventing wheels that exist. And the final one would be nice, but this is as `com.google.gwt.i18n.client.NumberFormat` which doesn't have that method. Using a `double` seems like the simplest solution - if one only needs a few decimal places its precision is more than enough. – Boris the Spider Feb 17 '16 at 08:33
  • @Boris yeah forgot this question was about GWT. So long ago. I think there is nothing wrong with "sanitising" the number string before parsing. – Strelok Feb 17 '16 at 13:06
  • To "sanitize" enhance the parse method to remove all LocaleInfo.getCurrentLocale().getNumberConstants().groupingSeparator() and replace all LocaleInfo.getCurrentLocale().getNumberConstants().decimalSeparator() with '.' . That covers all locales I can think of. – Alex K. Jan 15 '19 at 13:09
1

Take a look at GWT-Math.

npinti
  • 51,780
  • 5
  • 72
  • 96
  • I see that I can convert it to double and from there to BigDecimal. Will that be ok? do I loose anything in the way? – kroiz May 02 '12 at 12:32
  • 2
    If you can go from `String` to `BigDecimal` in one step you might as well do that since it will reduce any chances that the number is rounded off when cast to a `double`. – npinti May 02 '12 at 12:34