Reputation: 1271
Can you please help me with a generics. I have a requirement where I have a UI form but based on type, form changes completely. I have created Parent DTO with common fields and child DTOs for each type of form. Using vaadin for validation. How do I get this working. bind method on childdto giving error.
The type ChildlDTO does not define getTitle(capture#10-of ? extends ParentDTO) that is applicable here
The method writeBean(capture#10-of ? extends ParentDTO) in the type Binder is not applicable for the arguments (ParentDTO)
private ParentDTO dto= new ChildDTO();
private Binder<? extends ParentDTO> binder = new Binder<>(ParentDTO.class);
binder.forField(type).asRequired("Please select type")
.bind(ParentDTO::getType, ParentDTO::setType);
compile errors below for bind and write methods
binder.forField(title).asRequired("Please select Title")
.bind(ChildDTO::getTitle, ChildDTO::setTitle);
binder.writeBean(control);
Parent and child classes
public abstract class ParentDTO
public class ChildDTO extends ParentDTO {
Vaadin Binder
public class Binder<BEAN> implements Serializable {
bind and write methods
Binding<BEAN, TARGET> bind(ValueProvider<BEAN, TARGET> getter,
Setter<BEAN, TARGET> setter);
public void writeBean(BEAN bean) throws ValidationException {
Also
Upvotes: 0
Views: 358
Reputation: 5342
Just go with a Binder<ParentDTO>
, then you can also write extending classes to it.
However, you are not going to be able to do this
binder.forField(title).asRequired("Please select Title")
.bind(ChildDTO::getTitle, ChildDTO::setTitle);
As there's no guarantee that what is passed to it is a ChildDTO
.
If you need that method, then you could do something like this, and create one function for each type of DTO:
public Binder<ChildDTO> createChildBinder(ChildDTO bean) {
Binder<ChildDTO> binder = createBinder(bean);
TextField titleField = new TextField();
add(titleField);
binder.forField(titleField).asRequired()
.bind(ChildDTO::getTitle, ChildDTO::setTitle);
binder.readBean(bean);
return binder;
}
public Binder<ChildTwoDTO> createChildBinder(ChildTwoDTO bean) {
Binder<ChildTwoDTO> binder = createBinder(bean);
TextField languageField = new TextField();
add(languageField);
binder.forField(languageField).asRequired()
.bind(ChildTwoDTO::getLanguage, ChildTwoDTO::setLanguage);
binder.readBean(bean);
return binder;
}
public <T extends ParentDTO> Binder<T> createBinder(T bean) {
Binder<T> binder = new Binder<>();
binder.forField(typeField).asRequired("Better fill this...")
.bind(ParentDTO::getType, ParentDTO::setType);
return binder;
}
Upvotes: 1