PropertyFormatter screws up DoubleValidator

Hi,

I’ve some TextFields where I would like to enter numbers. I have a DoubleValidator attached to them.

However, we would like to have the number formatted with a euro-sign in front of the number. Basic stuff. But then Doublevalidator complains that it is no longer a number… why? Is Validation done before formatting? Can I override this behavior in a simple way?

Below is my unholy Formatter-class. I’ve also attached a screenshot as attachment.

Thank you in advance
//B

public class PRTCurrencyFormatter extends PropertyFormatter {

public PRTCurrencyFormatter() {
    super();
}

public PRTCurrencyFormatter(Property propertyDataSource) {
    super();
    setPropertyDataSource(propertyDataSource);
}

@Override
public Object parse(String formattedValue) throws Exception {
    formattedValue = formattedValue.replace(",", "");
    formattedValue = formattedValue.replace("\u20ac", "");
    formattedValue = formattedValue.trim();
    Integer tmp = Integer.parseInt(formattedValue);
    return tmp;
}

@Override
public String format(Object value) {
    if (value == null) {
        return "";
    }

    String tmp = value + "";
    tmp = tmp.trim();

    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < tmp.length(); i++) {
        int remainder = i % 3;
        if (remainder == 0 && i != 0) {
            sb.append(",");
        }
        sb.append(tmp.charAt(tmp.length() - 1 - i));
    }
    sb.append(" \u20ac");

    sb.reverse();

    return sb.toString();
}

@Override
public Class<?> getType() {
    return String.class;
}

}

16503.png

The PropertyFormatter is wrapping the original property. You have to unpack the original property in the validator.

Property realProperty = property instanceof Property.Viewer ? ((Property.Viewer) property).getPropertyDataSource() : property;

This has been reworked in Vaadin 7.

Some other suggestions:

  • use BigDecimal instead of Double
  • use DecimalFormat for formatting and parsing instead of self made String handling.

Vaadin is too smart for me. Say again what needs to be done?

Where in my factory method where I create the field should the above line be entered?

    if ("authorizedAmount".equals(propertyId)) {
        CustomTableTextField estimateAmount = new CustomTableTextField(new TextField());
        estimateAmount.setData(itemId); //rowId
        estimateAmount.setDescription("Authorised budget");
        estimateAmount.setRequired(true);
        estimateAmount.setRequiredError("Authorised budget is missing");
        estimateAmount.setImmediate(true);
        estimateAmount.setNullRepresentation("");
        estimateAmount.setPropertyDataSource(new PRTCurrencyFormatter(estimateAmount.getPropertyDataSource()));
        estimateAmount.addValidator(new DoubleValidator("Please choose a valid number as authorised budget amount"));
        addFieldToBeValidated(itemId.hashCode(), (String)propertyId, estimateAmount);
        estimateAmount.addBlurListener(estimateAmount);//Vaadin fighting back again, this was needed or else Vaadin would still display errors even though there were none. 
        return estimateAmount;
    }

For reference, the order is Field->Converter->Validator(s)->PropertyDataSource.

Converter converts a String to a Double, and the Validator checks if the Double is in the correct range. Any formatting you want need to go into the Converter.

ok, you are using the VAADIN DoubleValidator - this did not work in your case.

You have to perform the validation in your PRTCurrencyFormatter, like:

public Object parse(String formattedValue) throws Exception {
DecimalFormat df = new DecimalFormat(“#.###,##”, Locale.UK);
try {
Number number = df.parse(formattedValue);
return number.doubleValue(); // again: BigDecimal would be better
} catch (NumberFormatException e) {
throw new Validator.InvalidValueException(“Please choose a valid number as authorised budget amount”);
}
}

The decimal format pattern must be #,###.## - the forum did not let me change the post :wink:

Use
java.text.NumberFormat.getCurrencyInstance()
in the
Converter
(as Thomas wrote) - than you don’t need any validator.