Можете ли вы заставить TextField <BigDecimal>принимать как, так и.как десятичный разделитель? - PullRequest
7 голосов
/ 11 июля 2011

В приложении Wicket у меня есть текстовое поле десятичного числа:

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

Я хочу, чтобы он всегда принимал оба. (точка) и, (запятая) в качестве десятичного разделителя ( независимо от настроек языка браузера).

Для , показывающего значение, используется языковой стандарт сеанса [который в нашем случае является «fi» (-> запятая)], но здесь меня интересует, какое поле принимает в качестве ввода.

У меня вопрос: нужно ли изменить поле на TextField<String> и преобразовать в тип объекта домена (BigDecimal) вручную? Или есть какой-то способ использовать TextField<BigDecimal> (который позволяет, например, использовать MinimumValidator или RangeValidator от Wicket), и при этом он может принимать оба десятичных разделителя?

1 Ответ

13 голосов
/ 11 июля 2011

Благодаря комментарию @ bert и книге Wicket в действии я нашел подход, который работает. В классе Application укажите специальный конвертер для BigDecimals:

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

А в пользовательском конвертере convertToObject необходимо переопределить. NB : этого достаточно для наших потребностей; Подумайте о своих требованиях и адаптируйтесь по мере необходимости!

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.

...