How to set a custom BigDecimal converter to a TextField<BigDecimal> in Wicket 1.5?

Jonik picture Jonik · Dec 29, 2011 · Viewed 8.2k times · Source

Going from 1.4 to 1.5, there seem to be many undocumented changes in addition to the documented ones.

In 1.4 I had:

new TextField<BigDecimal>("capitalInput", 
        new PropertyModel<BigDecimal>(model, "capital")) {
    @Override
    public IConverter getConverter(Class<?> type) {
        return new MonetaryBigDecimalConverter();
    } 
};

With 1.5, I changed that like so (to match how getConverter() is now declared):

new TextField<BigDecimal>("capital", 
        new PropertyModel<BigDecimal>(model, "capital")) {
    @Override
    public <C> IConverter<C> getConverter(Class<C> type) {
        return new MonetaryBigDecimalConverter();
    }
};

Which my IDE shows as just unchecked assignment warning. But then trying to build the project it's actually a compilation error:

incompatible types
found   : com.company.MonetaryBigDecimalConverter
required: org.apache.wicket.util.convert.IConverter<C>

The custom MonetaryBigDecimalConverter looks something like this (1.5):

public class MonetaryBigDecimalConverter extends BigDecimalConverter {
    @Override
    public String convertToString(BigDecimal value, Locale locale) {
        // ...
    }
}

How can I make this work again?

Answer

svenmeier picture svenmeier · Jan 2, 2012

Since Wicket 1.5 converter has a generic type parameter:

IConverter<C>

Note that the type argument C of #getConverter() is not bound to the type parameter of your textfield, so you should test the requested type:

new TextField<BigDecimal>("capital", 
        new PropertyModel<BigDecimal>(model, "capital")) {
    @Override
    public <C> IConverter<C> getConverter(Class<C> type) {
        if (type == BigDecimal) {
            return (IConverter<C>) new MonetaryBigDecimalConverter();
        } else {
            return super.getConverter(type);
        }
    }
};

You have to explicitely cast your converter to the requested IConverter to quiet the compiler. Or with your workaround you're dropping into a raw type, thus sidestepping the problem.