FieldGroup Bind Combobox Bean

Buenas tardes,

Tengo una tabla que se llena con Beans que tienen como atributo otro bean:
public class Paciente {
private Empresa empresa;
}
A los pacientes lo puedo cargar correctamente en una tabla y mediante el uso de addNestedContainerProperty puedo observar en la tabla el nombre de la empresa a la que corresponde:

listadoPaciences.addNestedContainerProperty(“empresa.razonSocial”);.

Mi problema está en que para modificar esa empresa estoy utilizando un formulario que posee un ComboBox que es cargado con objetos “empresa” (todas las empresas levantadas de la BD). Esta carga es correcta. Lo que estoy tratando de hacer es que al seleccionar el paciente de la tabla el combo se posicione sobre la empresa correspondiente al paciente.
Para esto estoy utilizando la siguiente setencia:

fieldGroup.bind(this.getCmbEmpresa(),“empresa.razonSocial”);
Pero evidentemente estoy bindindeando mal ya que el combo no se posiciona en la empresa que corresponde.

El realizar algo similar con un combo que solo posee String funciona bien, pero mi problema es cuando el combo tiene Beans.
No se en que le estoy errando.
Saludos

Les cuento como lo resolvi a priori. Creo que quizas exista un bindeo de Bean a Combo pero no lo logré coseguir.
Por lo pronto lo que hice fue recorrer el Container del combo y compararlo con el Bean, en caso de ser iguales seteo el valor en el combo.
Otras soluciones son escuchadas y en caso de requerir lo que implemente estoy a disposición.

Saludos

Hola Matias!

Si nos pudieras proporcionar algo más de código sería más fácil identificar el problema.
Con lo que has dicho, puedo hacer alguna suposición que tal vez te ayude.

En primer lugar, Si quieres hacer binding con Beans, debes utilizar un BeanFieldGroup. Para editar un bean Paciente, debes llamar a BeanFieldGroup.setItemDatasource(bean).
Si no se actualizan los campos correctamente, puede probar llamando a BeanFieldGroup.discard() una vez has llamado a setItemDatasource(bean) para que vuelva a cargar los datos del datasource en los campos del FieldGroup.

También ten en cuenta que el itemId de los items del ComboBox debe ser el propio bean

Espero que te sirva de algo

Un saludo!

Buenas Matías,

Entiendo que al FieldGroup le estás pasandocomo ITEM data source el item que obtienes del table verdad?

Este Item tiena una property de id “empresa.razonSocial” . Y asociarlo via un bind al ComboBox lo que queremos es que se haga un setValue un el combo con el valor de la propertyid…

No sé si lo has hecho así pero probaría a definir un BeanContainer<T, Empresa> donde T sea el TIPO de la propiedad razonSocial de Empresa.

BeanContainer<T, Empresa> empresasContainer = new BeanContainer<T, Empresa>( Empresa.class); empresasContainer.setBeanPropertyId("razonSocial"); // Obtenemos todas las empresas y las cargamos al container Collection<Empresa> todasLasEmpresas = ...; empresasContainer.addAll(todasLasEmpresas); getCmbEmpresa().setContainerDataSource(empresasContainer); A ver si te sirve

Saludos,

Rodrigo, Omar gracias por tomarse tiempo.
Les comento basicamente que estoy tratando se seguir el modelo expuesto aqui: https://vaadin.com/wiki/-/wiki/Main/Creating+a+master-details+view+for+editing+persons

Probé usando un Objeto cargado en la tabla que tiene propiedades que a su vez no son objetos anidados (String, int, etc) todo funciona perfecto usando un FieldGroup. El bindeo se hace correctamente como esta en el link.

Ahora, si el objeto cargado en la tabla tiene a su vez tiene un objeto anidado (como es mi caso, Paciente tiene una Empresa) yo quiero eventualmente editar para el Paciente seleccionado su Empresa.
En mi formulario de edicion tengo TextFields para datos del paciente (Nombre, Apellido, etc) y para la empresa tengo el combo. Como les dije, los datos que son tipo String, int, etc no tengo problemas en bindearlos con FieldGroup.

Ahora, extrictamente con el combo, lo que hago es que cuando creo el formulario lo cargo previamente con todas las empresas que tengo en mi BD( no hay problemas con eso).
El problema que tengo es como bindear el objeto anidado Empresa que es una propiedad del Paciente (que es el que selecicona de la tabla)con el combo donde tengo cargadas todas las empresas para q se setee la que efectiavamente tiene el paciente.

Como dice Rodrigo, estoy intentando con un BeanFieldGroup. No se si ésta parte está bien ya que lo instancié de la siguiente manera:
private BeanFieldGroup beanFieldGroup = new BeanFieldGroup(Empresa.class);
lo bindeo asi:
beanFieldGroup.bind(this.getCmbEmpresa(), “empresa”);

y luego en el addValueChangeListener de la tabla lo que hago es esto:
formularioPacienteModificar.getFieldGroup().setItemDataSource(item); ← para los textefields. Se cargan bien
y para el combo
formularioPacienteModificar.getBeanFieldGroup().setItemDataSource(item); ← para el combo con las empresas

// tambien probe con esto

formularioPacienteModificar.getBeanFieldGroup().setItemDataSource(item.getBean().getEmpresa());
donde item es, como dice Omar, el datasource.

Si hago un sysout.println.out del item se ve que esta el objeto Empresa instanciado o sea es parte del item.
Aun asi no se setea el valor en Combo.
No se bien donde no estoy comprendiendo bien el funcionamiento.

Desde ya gracias y espero haber sido claro muchachos!
Saludos

De esto deduzco que tienes dos elementos FieldGroup? Uno para la propiedad “empresa” y otra para el resto de fields?
Si es así, te recomiendo utilizar sólo uno. Aquí tienes la opción de trabajar directamente con el bean de tipo Paciente, o con un Item que contenga las properties de Paciente. A mi, personalmente, si puedo trabajar directamente con beans, prefiero esa opción.

Supongamos que utilizas BeanFieldGroup y beans Paciente directamente. Haces los bindings para cada field del tipo Paciente, entre ellos:

beanFieldGroup.bind(getCmbEmpresa(), "empresa"); Para que el ComboBox te muestre la propiedad “razonSocial” como caption de los items que contiene, debes hacer lo siguiente:

getCmbEmpresa().setItemCaptionMode(ItemCaptionMode.PROPERTY); getCmbEmpresa().setItemCaptionPropertyId("razonSocial"); Una vez hecho esto cargas en el formulario el bean de tipo Paciente:

formularioPacienteModificar.getBeanFieldGroup().setItemDataSource(item.getBean()); Si no se te han actualizado alguno de los campos,

formularioPacienteModificar.getBeanFieldGroup().discard(); En definitiva, la propiedad a la que haces el binding en el ComboBox no es “empresa.razonSocial”, sino “empresa” directamente.
Todo esto asumiendo que el Item que obtienes de la tabla es BeanItem. Si el Item no tiene un bean detrás, requiere una aproximación un poco diferente respecto al ComboBox.

Rodrigo, sabes que estaba usando FieldGroup y BeanFieldGroup y siguiendo tu consejo deje solamente BeanFieldGroup. Lo que no me queda claro es si el BeanFieldGroup debe ser PacienteEmpresa o Empresa (asumo que debe ser el primero para binder todas las propiedades incluyendo Empresa)

private BeanFieldGroup<PacienteEmpresa> beanFieldGroup = new BeanFieldGroup<PacienteEmpresa>(PacienteEmpresa.class); Ahora bien, bindee luego de la siguiente manera:

beanFieldGroup.bind(this.getTxtApellido(), "apellido");       
....//demas componentes
beanFieldGroup.bind(this.getCmbEmpresa(), "empresa"); 

Luego en el escuchador de la tabla hice lo siguiente:

[code]
this.getFilterTablePacientes().addValueChangeListener(new Property.ValueChangeListener() {

        private static final long serialVersionUID = 1L;
        @Override
        public void valueChange(ValueChangeEvent event) {
        
            editaPaciente((PacienteEmpresa)getFilterTablePacientes().getValue());
        }
        private void editaPaciente(PacienteEmpresa paciente) {
            
            if(paciente != null){
            BeanItem<PacienteEmpresa> item = new BeanItem<PacienteEmpresa>(paciente);
            System.out.println("item:" + item);
            formularioPacienteModificar.getBeanFieldGroup().setItemDataSource(item);
            formularioPacienteModificar.getBeanFieldGroup().discard();                
            }
        }
    });

[/code]Todo se bindea correctamente en el formulario menos el combo. El combo al desplegarlo esta correctamente cargado con las empresas de la BD pero no logro dar en el clavo
PacienteEmpresa es el Bean que es un paciente y tiene como Bean anidado la empresa.
No se en que estoy fallando.
Desde ya gracias

Rodrigo, Omar encontre el problema para mi caso.
Debia generar el codigo
public int hashCode() y public boolean equals(Object obj) para mi clase Empresa!!
Estos links me ayudaron :
https://vaadin.com/forum/#!/thread/275487/275939
https://vaadin.com/forum/#!/thread/126904

Muchas Gracias muchachos!
Un abrazo

Me alegro de que lo consiguieras solucionar. Antes de leer tu último post te iba a preguntar precisamente por el método equals(), que como ya has descubierto, es el que utiliza ComboBox (o cualquier clase derivada de AbstractSelect) para averiguar cual de los items que contiene se ha seleccionado.

Un saludo!