package au.com.vaadinutils.fields; import javax.persistence.metamodel.SingularAttribute; import au.com.vaadinutils.crud.CrudEntity; import com.vaadin.addon.jpacontainer.EntityContainer; import com.vaadin.data.util.filter.Compare; import com.vaadin.ui.ComboBox; /** * A combobox which is dependent on a parent combo box. * * Imagine two entities with a parent child relationship. * You create a EntityComboBox to display the parent entities. * You then create a DependantComboBox which links to the parent ComboBox. * When a user selects an entity in the parent combobox that selection * is used to filter the set of child entities displayed in the DependantComboBox. * * Usage: * JpaContainer<Publication> publicationContainer; * JpaContainer<Edition> editionContainer; * * publicationField = new EntityComboBox<Publication>("Publication", pulicationContainer, "Publication"); * * editionField = new DependantComboBox<Publication, Edition>("Edition", publicationField, editionContainer, * "publication", "name"); * * @author bsutton * * @param <Parent> * the Entity type of the items contained in the Parent container * @param <E> * the Entity type of the items contained in the Child container */ public class DependantComboBox<Parent extends CrudEntity, E extends CrudEntity> extends EntityComboBox<E> { private static final long serialVersionUID = 1L; /** * @param label label to display adjacent to the ComboBox. * @param parent the parent ComboBox that this ComboBox is dependent on. * @param childContainer the container used to fill the child ComboBox. * @param childForeignAttribute attribute of the child entity that links back to the parent entity. */ public DependantComboBox(String label, final ComboBox parent, final EntityContainer<E> childContainer, final SingularAttribute<E, Parent> childForeignAttribute, final SingularAttribute<E, ? extends Object> displayAttribute) { super(label, childContainer, displayAttribute); addParentHandler(parent, childContainer, childForeignAttribute); } public DependantComboBox(String label, final ComboBox parent, final EntityContainer<E> childContainer, final SingularAttribute<E, Parent> childForeignAttribute, final String displayAttribute) { super(label, childContainer, displayAttribute); addParentHandler(parent, childContainer, childForeignAttribute); } private void addParentHandler(final ComboBox parent, final EntityContainer<E> childContainer, final SingularAttribute<E, Parent> childForeignAttribute) { parent.addValueChangeListener(new ValueChangeListener() { private static final long serialVersionUID = 1L; @Override public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) { @SuppressWarnings("unchecked") Parent parentEntity = ((Parent) parent.getConvertedValue()); childContainer.removeAllContainerFilters(); childContainer.addContainerFilter(new Compare.Equal(childForeignAttribute.getName(), parentEntity)); DependantComboBox.this.setContainerDataSource(childContainer); DependantComboBox.this.setValue(null); } }); } }