Problem with Binder class

Hi everybody,

I’m trying to do a exercice with Grid and the Binder class like a Alejandro’s exercice. This is my architecture:
(https://ibb.co/kGQkgd)

I did a bit changes, I use “Principal.java” to select what screen loads to them refill the form. Finally I put the Grid in “Resumen.java”.
(https://ibb.co/iEcbnJ)

My problem is that allways, in the next file, the binder objects is null:

package com.example.Vistas;

import com.example.DTOs.SegurosDTO;
import com.example.Enums.Religion;
import com.example.Services.SegurosService;
import com.vaadin.data.Binder;
import com.vaadin.navigator.View;
import com.vaadin.ui.Button;
import com.vaadin.ui.CheckBoxGroup;
import com.vaadin.ui.DateField;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.NativeSelect;
import com.vaadin.ui.RadioButtonGroup;
import com.vaadin.ui.TextField;
import com.vaadin.ui.themes.ValoTheme;

public class FormularioIncendio extends FormLayout implements View{

	private SegurosService segurosService = SegurosService.getInstance();
	private SegurosDTO segurosDTO;
	private Binder<SegurosDTO> binder = new Binder<>(SegurosDTO.class);
	
//	Componentes del Form
	private TextField tipo = new TextField("Tipo seguro:");
	private TextField titular = new TextField("Titular:");
	private DateField hasta =  new DateField("Válido hasta:");
	private NativeSelect<Religion> religion = new NativeSelect<>("Religión");
	private RadioButtonGroup<String> enfermo = new RadioButtonGroup<>("¿Le gustan las cerillas?:");
	private CheckBoxGroup<String> actividades = new CheckBoxGroup<>("Prefernecias deportivas:");
	private Button salvar = new Button("Salvar");
	private Button limpiar = new Button("Borrar");
	
	private Resumen resumenLocal;
	
	public FormularioIncendio(Resumen resumen) {
		this.resumenLocal = resumen;
		
		HorizontalLayout botonera = new HorizontalLayout(salvar, limpiar);
		addComponents(tipo, titular, hasta, religion, enfermo, actividades, botonera);
		
//----------- Configuracion de Valores -----------
		
//		Setteo de tipo
		tipo.setEnabled(false);
		tipo.setValue("Incendio");
		
//		Carga del "Combo" de religion 
		religion.setItems(Religion.values());
		
//---------- Propio del tipo -------------
//		Carga de RadioButton
		enfermo.setItems("Si", "No");
		
//		Carga de multiselección
		actividades.setItems("Cazar gamusinos", "Puenting", "Leer Biblia");
//----------------------------------------
		
		salvar.setStyleName(ValoTheme.BUTTON_FRIENDLY);
		limpiar.setStyleName(ValoTheme.BUTTON_DANGER);
		
		binder.bindInstanceFields(this);
		
		limpiar.addClickListener(e -> this.limpiarClick());
		salvar.addClickListener(e -> this.salvarClick());
		
		setMargin(true);
	}
	
	private void limpiarClick() {
		titular.clear();
		hasta.clear();
		religion.clear();
		enfermo.clear();
		actividades.clear();
	}
	
	private void salvarClick() {
		segurosService.save(segurosDTO);
		this.limpiarClick();
	}
}

Can someone explain me where is the problem?, thanks a lot

I don’t know if I have explained good but my problem is:

private void salvarClick() {
	segurosService.save(segurosDTO);
	this.limpiarClick();
}

There “segurosDTO” is always null.

Hi,

Do you ever set that segurosDTO to anything? If you are creating new entities with that UI then you are missing somethinglike:

segurosDTO = new SegurosDTO();
binder.setBean(segurosDTO);

cheers,
matti

Hi Matti,

Thanks a lot for your answer, I don’t initialize the class because in the Alejandro’s example he didn’t it:

package my.vaadin.app;

import com.vaadin.data.Binder;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.ui.Button;
import com.vaadin.ui.DateField;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.NativeSelect;
import com.vaadin.ui.TextField;
import com.vaadin.ui.themes.ValoTheme;

public class CustomerForm extends FormLayout {

    private TextField firstName = new TextField("First name");
    private TextField lastName = new TextField("Last name");
    private TextField email = new TextField("Email");
    private NativeSelect<CustomerStatus> status = new NativeSelect<>("Status");
    private DateField birthdate = new DateField("Birthday");
    private Button save = new Button("Save");
    private Button delete = new Button("Delete");

    private CustomerService service = CustomerService.getInstance();
    private Customer customer;
    private MyUI myUI;
    private Binder<Customer> binder = new Binder<>(Customer.class);

    public CustomerForm(MyUI myUI) {
        this.myUI = myUI;

        setSizeUndefined();
        HorizontalLayout buttons = new HorizontalLayout(save, delete);
        addComponents(firstName, lastName, email, status, birthdate, buttons);

        status.setItems(CustomerStatus.values());
        save.setStyleName(ValoTheme.BUTTON_PRIMARY);
        save.setClickShortcut(KeyCode.ENTER);

        binder.bindInstanceFields(this);

        save.addClickListener(e -> this.save());
        delete.addClickListener(e -> this.delete());
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
        binder.setBean(customer);

        // Show delete button for only customers already in the database
        delete.setVisible(customer.isPersisted());
        setVisible(true);
        firstName.selectAll();
    }

    private void delete() {
        service.delete(customer);
        myUI.updateList();
        setVisible(false);
    }

    private void save() {
        service.save(customer);
        myUI.updateList();
        setVisible(false);
    }
}

I trying to do for other way but I want to know how it’s with this class

The edited bean is set in the setCustomer method, which is probably called in another class that is using the editor. You can see the same pattern in [our tutorial]
(https://vaadin.com/docs/v8/framework/tutorial.html) and for example in my [Spring example]
(https://github.com/mstahv/spring-data-vaadin-crud).

cheers,
matti

Thanks Matti,

I followed this tutorial in my first try but now I use other architecture. Following the example I could run the application correctly but with finally with my reorder I have been to use other way to set the class without Binder. I used the typical setter.

private void salvarClick() {
		
//----------------- SIN BINDER-----------------
		segurosDTO = new SegurosDTO();
		
		segurosDTO.setTipo(tipo.getValue());
		segurosDTO.setTitular(titular.getValue());
		segurosDTO.setCaducidad(hasta.getValue());
		segurosDTO.setCreencia(religion.getValue());
		
		if(enfermo.getValue().equalsIgnoreCase("SI")) {
			segurosDTO.setCerillas(true);
		}
		else {
			segurosDTO.setCerillas(false);
		}
		
		String[] listActividades = String.valueOf(actividades.getValue()).split(",");
		
		segurosDTO.setPreferencias(listActividades);
//-------------------------------------------
		segurosService.save(segurosDTO);
		this.limpiarClick();
	}

Thanks a lot for your help, cheers.

That’s what we call manual data binding. Bit more code to maintain, but dead simple to implement.