Trouble create a abstract Vaadin CRM demo form class

Viewed 68

In Vaadin CRM demo (https://vaadin.com/docs/latest/flow/tutorials/in-depth-course), I try to create a abstract form class for ContactForm to inheritance from. Here is the code:

public abstract class AbstractForm<T> extends FormLayout {
    public T entity;

    Binder<T> binder;
    Button save = new Button("Save");
    Button delete = new Button("Delete");
    Button close = new Button("Cancel");

    protected Component createButtonsLayout() {
        save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
        close.addThemeVariants(ButtonVariant.LUMO_TERTIARY);

        save.addClickShortcut(Key.ENTER);
        close.addClickShortcut(Key.ESCAPE);

        save.addClickListener(event -> validateAndSave());
        delete.addClickListener(event -> fireEvent(new DeleteEvent(this, entity)));
        close.addClickListener(event -> fireEvent(new CloseEvent(this)));


        binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid()));

        return new HorizontalLayout(save, delete, close);
    }

    protected void validateAndSave() {
        try {
            binder.writeBean(entity);
            fireEvent(new SaveEvent(this, entity));
        } catch (ValidationException e) {
            e.printStackTrace();
        }
    }

    public <E extends ComponentEvent<?>> Registration addListener(Class<E> eventType, ComponentEventListener<E> listener) {
        return getEventBus().addListener(eventType, listener);
    }

    public void setEntity(T entity) {
        this.entity = entity;
        binder.readBean(entity);
    }


    public abstract class EntityFormEvent extends ComponentEvent<AbstractForm<T>> {
        private final T entity;

        protected EntityFormEvent(AbstractForm source, T entity) {
            super(source, false);
            this.entity = entity;
        }

        public T getEntity() {
            return entity;
        }
    }

    public class SaveEvent extends EntityFormEvent {
        SaveEvent(AbstractForm source, T entity) {
            super(source, entity);
        }
    }

    public class DeleteEvent extends EntityFormEvent {
        DeleteEvent(AbstractForm source, T entity) {
            super(source, entity);
        }

    }

    public class CloseEvent extends EntityFormEvent {
        CloseEvent(AbstractForm source) {
            super(source, null);
        }
    }
}

public class ContactForm extends AbstractForm<Contact> {
  TextField firstName = new TextField("First name");
  TextField lastName = new TextField("Last name");
  EmailField email = new EmailField("Email");
  ComboBox<Status> status = new ComboBox<>("Status");
  ComboBox<Company> company = new ComboBox<>("Company");
  Binder<Contact> binder = new BeanValidationBinder<>(Contact.class);

  public ContactForm(List<Company> companies, List<Status> statuses) {
    addClassName("contact-form");
    binder.bindInstanceFields(this);

    company.setItems(companies);
    company.setItemLabelGenerator(Company::getName);
    status.setItems(statuses);
    status.setItemLabelGenerator(Status::getName);
    add(firstName,
        lastName,
        email,
        company,
        status,
        createButtonsLayout()); 
  }
}

@Component
@Scope("prototype")
@Route(value="", layout = MainLayout.class)
@PageTitle("Contacts | Vaadin CRM")
@PermitAll
public class ListView extends VerticalLayout {
    Grid<Contact> grid = new Grid<>(Contact.class);
    TextField filterText = new TextField();
    ContactForm form;
    CrmService service;

    public ListView(CrmService service) {
        this.service = service;
        addClassName("list-view");
        setSizeFull();
        configureGrid();

        form = new ContactForm(service.findAllCompanies(), service.findAllStatuses());
        form.setWidth("25em");
        form.addListener(ContactForm.SaveEvent.class, this::saveContact);
        form.addListener(ContactForm.DeleteEvent.class, this::deleteContact);
        form.addListener(ContactForm.CloseEvent.class, e -> closeEditor());

        FlexLayout content = new FlexLayout(grid, form);
        content.setFlexGrow(2, grid);
        content.setFlexGrow(1, form);
        content.setFlexShrink(0, form);
        content.addClassNames("content", "gap-m");
        content.setSizeFull();

        add(getToolbar(), content);
        updateList();
        closeEditor();
        grid.asSingleSelect().addValueChangeListener(event ->
            editContact(event.getValue()));
    }

    private void configureGrid() {
        grid.addClassNames("contact-grid");
        grid.setSizeFull();
        grid.setColumns("firstName", "lastName", "email");
        grid.addColumn(contact -> contact.getStatus().getName()).setHeader("Status");
        grid.addColumn(contact -> contact.getCompany().getName()).setHeader("Company");
        grid.getColumns().forEach(col -> col.setAutoWidth(true));
    }

    private HorizontalLayout getToolbar() {
        filterText.setPlaceholder("Filter by name...");
        filterText.setClearButtonVisible(true);
        filterText.setValueChangeMode(ValueChangeMode.LAZY);
        filterText.addValueChangeListener(e -> updateList());

        Button addContactButton = new Button("Add contact");
        addContactButton.addClickListener(click -> addContact());

        HorizontalLayout toolbar = new HorizontalLayout(filterText, addContactButton);
        toolbar.addClassName("toolbar");
        return toolbar;
    }

    private void saveContact(ContactForm.SaveEvent event) {
        service.saveContact(event.getEntity());
        updateList();
        closeEditor();
    }

    private void deleteContact(ContactForm.DeleteEvent event) {
        service.deleteContact(event.getEntity());
        updateList();
        closeEditor();
    }

    public void editContact(Contact contact) {
        if (contact == null) {
            closeEditor();
        } else {
            form.setEntity(contact);
            form.setVisible(true);
            addClassName("editing");
        }
    }

    void addContact() {
        grid.asSingleSelect().clear();
        editContact(new Contact());
    }

    private void closeEditor() {
        form.setEntity(null);
        form.setVisible(false);
        removeClassName("editing");
    }

    private void updateList() {
        grid.setItems(service.findAllContacts(filterText.getValue()));
    }


}



I keep getting "incompatible types: cannot infer functional interface descriptor for com.vaadin.flow.component.ComponentEventListener" on build error.

0 Answers
Related