BigDecimalField output with commas from Binder

I am using BigDecimalFields, and IntegerFields with a Binder and I would like to the output to contain commas and guaranteed decimal places for currency. For BigDecimals, my output is currently like ‘10000.00’ where I would want ‘10,000.00’. For integers, my output is currently like ‘9999’ where I would want ‘9,999’.

Is there a setting or CSS style that I am missing?
Or a better field type for currency, commas, and decimals?
Or a way to add a number/decimal string formatter to BigDecimalFields?

Thanks,
Kevin

Note: At first, I was using doubles in TextFields with a StringToDoubleConverter. This produced commas in the output. I decided to attempt to use the stronger typed BigDecimalField but I lost the commas, gained prevention typing of alphabetic characters, and gained static 2 decimal places for pennies (even when 1.00). So, I can revert to TextFields if needed. Old code where fieldUSDAmount is a TextField:

binder.forMemberField(fieldUSDAmount).withConverter(new StringToDoubleConverter("Enter a dollar amount; no $ needed."));

You can create/extend your own StringToDoubleConverter, where you can define your desired NumberFormat to be used in its convertToPresentation or getFormat method.

Thanks. I actually just found the docs that hint at that a moment ago. Working on that now. I will post my solution in a bit.

Vaadin docs: https://vaadin.com/docs/v14/flow/binding-data/tutorial-flow-components-binder-validation/#implementing-the-converter-interface

“Converter” was the magic word missing from my searches.

Working great now. Thanks again. I’ve only been playing with Vaadin for ~3 weeks and I am loving it.

My currency converter solution, which is probably like 20 other solutions that are difficult to find due to magical search terms:

import com.vaadin.flow.data.binder.Result;
import com.vaadin.flow.data.binder.ValueContext;
import com.vaadin.flow.data.converter.Converter;

import java.math.BigDecimal;
import java.text.DecimalFormat;

/* Vaadin docs source:
   https://vaadin.com/docs/v14/flow/binding-data/tutorial-flow-components-binder-validation/#implementing-the-converter-interface
 */

/**
 * Converter that handles a simple situation for TextField to BigDecimal.
 * Simple usage below.
 *
 * Declaration of TextField in class that extends PolymerTemplate:
 * `@Id("textFieldWithUSDAmount")                       // backtick to escape the @ for JavaDoc
 * private TextField textFieldWithUSDAmount;
 *
 * Binder declaration and attach converter to TextField:
 * BeanValidationBinder<YourBeanClass> binder = new BeanValidationBinder<>(YourBeanClass.class);
 * binder.forMemberField(textFieldWithUSDAmount).withConverter(new CurrencyConverter());
 */
public class CurrencyConverter implements Converter<String, BigDecimal> {
    @Override
    public Result<BigDecimal> convertToModel(String fieldValue, ValueContext context) {
        // Produces a converted value or an error
        try {
            // remove undesired dollar signs and commas
            String simpleString = fieldValue.replaceAll("[€$,]
", "");
            // ok is a static helper method that creates a Result
            return Result.ok(new BigDecimal(simpleString));
        } catch (NumberFormatException e) {
            // error is a static helper method that creates a Result
            return Result.error("Enter a number.");
        }
    }

    // number output format that inserts commas and guarantees two decimal places
    /* NOTE: I insert a dollar sign icon at the start of the TextField with:
             import com.vaadin.flow.component.icon.Icon;
             import com.vaadin.flow.component.icon.VaadinIcon;
             textFieldWithUSDAmount.setPrefixComponent(new Icon(VaadinIcon.DOLLAR));
     */
    private static final DecimalFormat decimalFormat = new DecimalFormat("###,###,###,###,###.00");

    @Override
    public String convertToPresentation(BigDecimal bigDecimal, ValueContext context) {
        // Converting to the field type should
        // always succeed, so there is no support for
        // returning an error Result.
        return decimalFormat.format(bigDecimal);
    }
}