8

在 Wicket 应用程序中,我有一个十进制数字文本字段:

 TextField<BigDecimal> f = 
     new TextField<BigDecimal>("f", new PropertyModel<BigDecimal>(model, "share"));

我希望它始终接受两者。(点)和 ,(逗号)作为小数分隔符(与浏览器的区域设置无关)。

为了显示该值,使用了会话的语言环境[在我们的例子中,它被强制为“fi”(-> 逗号)],但在这里我感兴趣的是该字段接受什么作为输入。

我的问题是,我是否必须将字段更改为TextField<String>,并手动转换为域对象的类型(BigDecimal)?或者有什么方法可以使用TextField<BigDecimal>(例如允许使用 Wicket 的 MinimumValidator 或 RangeValidator),并且仍然让它接受两个小数分隔符?

4

1 回答 1

15

感谢@bert 的评论和Wicket in Action一书,我找到了一种行之有效的方法。在 Application 类中为 BigDecimals 指定一个自定义转换器:

@Override
protected IConverterLocator newConverterLocator() {
    ConverterLocator converterLocator = new ConverterLocator();
    converterLocator.set(BigDecimal.class, new CustomBigDecimalConverter());
    return converterLocator;
}

并且在自定义转换器中,convertToObject需要被覆盖。注意:这足以满足我们的需求;考虑您的要求并根据需要进行调整!

public class CustomBigDecimalConverter extends BigDecimalConverter {

    @Override
    public BigDecimal convertToObject(String value, Locale locale) {
        // NB: this isn't universal & your mileage problably varies!
        // (Specifically, this breaks if '.' is used as thousands separator)
        if ("fi".equals(locale.getLanguage())) {
            value = value.replace('.', ',');
        }
        return super.convertToObject(value, locale);
    }
}

编辑:离题,但我也想记录一下。我们需要我们的应用程序支持小数点后 4 位,而我们的自定义 BigDecimal 转换器也很好地解决了这个问题。

  @Override
    public String convertToString(Object value, Locale locale) {
        NumberFormat fmt = getNumberFormat(locale);
        fmt.setMaximumFractionDigits(4); // By default this is 3.
        return fmt.format(value);
    }

在此自定义之后,像 2.0005 这样的十进制数将显示为 2.0005 而不是 2。

于 2011-07-11T11:29:36.657 回答