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 class ComboBox
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 a ComboBox
.
ComboBox
provides two overloaded versions of setConverter()
:
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>
where T
is the data type managed by the field (e.g. Strings for text fields, Date
for a DateField
, Object
for ComboBoxes
). 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 a Label
you can use a StringToDateConverter
to correctly display a Date
object, which has been set as the value of the Label
, in a properly localized way.
How is that with select components such as ComboBox
? Here the type T
is Object
. 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 a BeanItemContainer
as the data source of a ComboBox
, the container's item IDs (and hence the selected value of the ComboBox
) are the contained JavaBean objects themselves. The concrete type of the item IDs depends on the container implementation used. Therefore, select components are Field
components with value type Object
. In other words, select components use Object
as presentation type.
That is why you can only set a converter instance on a select component whose generic PRESENTATION
type is Object
. The model type can be chosen freely. And this also explain why you can't set a converter with presentation type Boolean
and model type Date
on a ComboBox
-- ComboBox
doesn't use Boolean
as presentation type.
I wrote a blog post about Vaadin FieldGroups
which also provides a good example for a use case when to use a Converter<Object, ?>
on a ComboBox
. 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 of Date
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With