123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- ---
- title: Automatic Form Generation
- order: 8
- layout: page
- ---
-
- [[jpacontainer.fieldfactory]]
- = Automatic Form Generation
-
- The JPAContainer [classname]#FieldFactory# is an implementation of the
- [interfacename]#FormFieldFactory# and [interfacename]#TableFieldFactory#
- interfaces that can generate fields based on JPA annotations in a POJO. It goes
- further than the [classname]#DefaultFieldFactory#, which only creates simple
- fields for the basic data types. This way, you can easily create forms to input
- entities or enable editing in tables.
-
- The generated defaults are as follows:
-
- [options="header"]
- |===============
- |Annotation|Class Mapping
- |[literal]#++@ManyToOne++#|[classname]#NativeSelect#
- |[literal]#++@OneToOne++#, [literal]#++@Embedded++#|Nested [classname]#Form#
- |[literal]#++@OneToMany++#, [literal]#++@ElementCollection++#|[classname]#MasterDetailEditor# (see below)
- |[literal]#++@ManyToMany++#|Selectable [classname]#Table#
-
- |===============
-
- The field factory is recursive, so that you can edit a complex object tree with one form.
-
- [[jpacontainer.fieldfactory.configuring]]
- == Configuring the Field Factory
-
- The [classname]#FieldFactory# is highly configurable with various configuration settings and by extending.
- // You need to make the configuration before ...
-
- The [methodname]#setMultiSelectType()# and [methodname]#setSingleSelectType()#
- allow you to specify a selection component that is used instead of the default
- for a field with [literal]#++@ManyToMany++# and [literal]#++@ManyToOne++#
- annotation, respectively. The first parameter is the class type of the field,
- and the second parameter is the class type of a selection component. It must be
- a sub-class of [classname]#AbstractSelect#.
-
- The [methodname]#setVisibleProperties()# controls which properties (fields) are
- visible in generated forms, subforms, and tables. The first paramater is the
- class type for which the setting should be made, followed by the IDs of the
- visible properties.
-
- The configuration should be done before binding the form to a data source as
- that is when the field generation is done.
-
- Further configuration must be done by extending the many protected methods.
- Please see the API documentation for the complete list.
-
-
- [[jpacontainer.fieldfactory.using]]
- == Using the Field Factory
-
- The most basic use case for the JPAContainer [classname]#FieldFactory# is with a
- [classname]#Form# bound to a container item:
-
-
- ----
- // Have a persistent container
- final JPAContainer<Country> countries =
- JPAContainerFactory.make(Country.class, "book-examples");
-
- // For selecting an item to edit
- final ComboBox countrySelect =
- new ComboBox("Select a Country", countries);
- countrySelect.setItemCaptionMode(Select.ITEM_CAPTION_MODE_PROPERTY);
- countrySelect.setItemCaptionPropertyId("name");
-
- // Country Editor
- final Form countryForm = new Form();
- countryForm.setCaption("Country Editor");
- countryForm.addStyleName("bordered"); // Custom style
- countryForm.setWidth("420px");
- countryForm.setBuffered(true);
- countryForm.setEnabled(false);
-
- // When an item is selected from the list...
- countrySelect.addValueChangeListener(new ValueChangeListener(){
- @Override
- public void valueChange(ValueChangeEvent event) {
- // Get the item to edit in the form
- Item countryItem =
- countries.getItem(event.getProperty().getValue());
-
- // Use a JPAContainer field factory
- // - no configuration is needed here
- final FieldFactory fieldFactory = new FieldFactory();
- countryForm.setFormFieldFactory(fieldFactory);
-
- // Edit the item in the form
- countryForm.setItemDataSource(countryItem);
- countryForm.setEnabled(true);
-
- // Handle saves on the form
- final Button save = new Button("Save");
- countryForm.getFooter().removeAllComponents();
- countryForm.getFooter().addComponent(save);
- save.addClickListener(new ClickListener() {
- @Override
- public void buttonClick(ClickEvent event) {
- try {
- countryForm.commit();
- countryForm.setEnabled(false);
- } catch (InvalidValueException e) {
- }
- }
- });
- }
- });
- countrySelect.setImmediate(true);
- countrySelect.setNullSelectionAllowed(false);
- ----
- See the http://demo.vaadin.com/book-examples-vaadin7/book#jpacontainer.fieldfactory.formonetoone[on-line example, window="_blank"].
-
- This would create a form shown in <<figure.jpacontainer.fieldfactory.using>>.
-
- [[figure.jpacontainer.fieldfactory.using]]
- .Using FieldFactory with One-to-Many Relationship
- image::img/fieldfactory-form.png[]
-
- If you use Hibernate, you also need to pass an
- [classname]#EntityManagerPerRequestHelper#, either for the constructor or with
- [methodname]#setEntityManagerPerRequestHelper()#
- ifdef::web[]
- , as described in
- <<dummy/../../../framework/jpacontainer/jpacontainer-hibernate#jpacontainer.hibernate.em-per-request,"The
- EntityManager-Per-Request
- pattern">>
- endif::web[]
- .
-
-
- [[jpacontainer.fieldfactory.masterdetaileditor]]
- == Master-Detail Editor
-
- The [classname]#MasterDetailEditor# is a field component that allows editing an
- item property that has one-to-many relationship. The item can be a row in a
- table or bound to a form. It displays the referenced collection as an editable
- [classname]#Table# and allows adding and removing items in it.
-
- You can use the [classname]#MasterDetailEditor# manually, or perhaps more
- commonly use a JPAContainer [classname]#FieldFactory# to create it
- automatically. As shown in the example in
- <<figure.jpacontainer.fieldfactory.using>>, the factory creates a
- [classname]#MasterDetailEditor# for all properties with a
- [literal]#++@OneToMany++# or an [literal]#++@ElementCollection++# annotation.
|