I've made a converter:
public class BooleanToDateConverter implements Converter<Boolean, Date> {
private static final long serialVersionUID = 1L;
@Override
public Date convertToModel(Boolean value, Class<? extends Date> targetType, Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
if (value == true) {
return new Date();
} else {
return null;
}
}
@Override
public Boolean convertToPresentation(Date value, Class<? extends Boolean> targetType, Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
if (value == null) {
return false;
} else {
return true;
}
}
@Override
public Class<Date> getModelType() {
return Date.class;
}
@Override
public Class<Boolean> getPresentationType() {
return Boolean.class;
}
}
Then I have a Vaadin ComboBox myComboBox I try to set my converter to it:
myComboBox.setConverter(new BooleanToDateConverter());
Then I get an error in Eclipse saying:
The method setConverter(Class<?>) in the type AbstractField<Object> is not applicable for the arguments (BooleanToDateConverter)
However, I've seen other converters being used similarly and they don't get errors. Why?
Your code cannot be compiled because there is no
setConverter()
method available on classComboBox
that fits your custom converter. Let me explain how converters are used on select components and what is the idea behind the specific method signatures you find for setting converters on aComboBox
.ComboBox
provides two overloaded versions ofsetConverter()
:setConverter(Class<?> datamodelType)
: set a pre-registered converter for the given data model typesetConverter(Converter<Object, ?> converter)
: set a concrete converter instanceBoth of these methods are actually inherited from class
AbstractField<T>
whereT
is the data type managed by the field (e.g. Strings for text fields,Date
for aDateField
,Object
forComboBoxes
). A converter is typically used to convert between a presentation type (such as the textual representation of a value on the UI) and its internal model type (such as a date, a monetary value or a custom JavaBean). So, for instance, if you have aLabel
you can use aStringToDateConverter
to correctly display aDate
object, which has been set as the value of theLabel
, in a properly localized way.How is that with select components such as
ComboBox
? Here the typeT
isObject
. The data type of a select component actually represents the item ID of the selected item from the underlying container data source. So, if you use aBeanItemContainer
as the data source of aComboBox
, the container's item IDs (and hence the selected value of theComboBox
) are the contained JavaBean objects themselves. The concrete type of the item IDs depends on the container implementation used. Therefore, select components areField
components with value typeObject
. In other words, select components useObject
as presentation type.That is why you can only set a converter instance on a select component whose generic
PRESENTATION
type isObject
. The model type can be chosen freely. And this also explain why you can't set a converter with presentation typeBoolean
and model typeDate
on aComboBox
--ComboBox
doesn't useBoolean
as presentation type.I wrote a blog post about Vaadin
FieldGroups
which also provides a good example for a use case when to use aConverter<Object, ?>
on aComboBox
. You can find this article at http://blog.oio.de/2014/04/25/select-nested-javabeans-vaadin-fieldgroup/.I don't know what you want to achieve with your code, because a converter between a presentation type of
Boolean
and a model type ofDate
doesn't make much sense. I can only guess that you want to implementat some sort of decision logic, maybe to decide whether or not a date has been set? In that case you need to take a different approach.For reference, have a look at the Book of Vaadin on Converters.