You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AbstractBasicCrud.java 9.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. package com.vaadin.tests.fieldgroup;
  2. import java.util.Iterator;
  3. import java.util.Map;
  4. import com.vaadin.annotations.PropertyId;
  5. import com.vaadin.server.VaadinRequest;
  6. import com.vaadin.shared.ui.ContentMode;
  7. import com.vaadin.shared.util.SharedUtil;
  8. import com.vaadin.tests.components.AbstractTestUIWithLog;
  9. import com.vaadin.ui.Alignment;
  10. import com.vaadin.ui.Button;
  11. import com.vaadin.ui.CheckBox;
  12. import com.vaadin.ui.Component;
  13. import com.vaadin.ui.GridLayout;
  14. import com.vaadin.ui.HorizontalLayout;
  15. import com.vaadin.ui.Label;
  16. import com.vaadin.ui.Notification;
  17. import com.vaadin.ui.Notification.Type;
  18. import com.vaadin.ui.themes.ValoTheme;
  19. import com.vaadin.v7.data.Validator.InvalidValueException;
  20. import com.vaadin.v7.data.fieldgroup.BeanFieldGroup;
  21. import com.vaadin.v7.data.fieldgroup.FieldGroup.CommitException;
  22. import com.vaadin.v7.data.util.BeanItem;
  23. import com.vaadin.v7.data.util.BeanItemContainer;
  24. import com.vaadin.v7.data.validator.IntegerRangeValidator;
  25. import com.vaadin.v7.ui.ComboBox;
  26. import com.vaadin.v7.ui.Field;
  27. import com.vaadin.v7.ui.TextField;
  28. public abstract class AbstractBasicCrud extends AbstractTestUIWithLog {
  29. protected AbstractForm form;
  30. protected static String[] columns = { "firstName", "lastName", "gender",
  31. "birthDate", "age", "alive", "address.streetAddress",
  32. "address.postalCode", "address.city", "address.country" };
  33. protected BeanItemContainer<ComplexPerson> container = ComplexPerson
  34. .createContainer(100);;
  35. {
  36. container.addNestedContainerBean("address");
  37. }
  38. protected ComboBox formType;
  39. /*
  40. * (non-Javadoc)
  41. *
  42. * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server.
  43. * VaadinRequest)
  44. */
  45. @Override
  46. protected void setup(VaadinRequest request) {
  47. getLayout().setSizeFull();
  48. getLayout().setSpacing(true);
  49. getContent().setSizeFull();
  50. form = new CustomForm();
  51. formType = new ComboBox();
  52. formType.setNullSelectionAllowed(false);
  53. formType.setWidth("300px");
  54. formType.addItem(form);
  55. formType.setValue(form);
  56. formType.addItem(new AutoGeneratedForm(TextField.class));
  57. formType.addItem(new AutoGeneratedForm(Field.class));
  58. Iterator<?> iterator = formType.getItemIds().iterator();
  59. formType.setItemCaption(iterator.next(), "TextField based form");
  60. formType.setItemCaption(iterator.next(),
  61. "Auto generated form (TextFields)");
  62. formType.setItemCaption(iterator.next(),
  63. "Auto generated form (Any fields)");
  64. formType.addValueChangeListener(event -> {
  65. AbstractForm oldForm = form;
  66. form = (AbstractForm) formType.getValue();
  67. replaceComponent(oldForm, form);
  68. });
  69. addComponent(formType);
  70. }
  71. public class CustomForm extends AbstractForm {
  72. private TextField firstName = new TextField("First name");
  73. private TextField lastName = new TextField("Last name");
  74. private TextField gender = new TextField("Gender");
  75. private TextField birthDate = new TextField("Birth date");
  76. private TextField age = new TextField("Age");
  77. private CheckBox alive = new CheckBox("Alive");
  78. private Label errorLabel = new Label((String) null, ContentMode.HTML);
  79. @PropertyId("address.streetAddress")
  80. private TextField address_streetAddress = new TextField(
  81. "Street address");
  82. @PropertyId("address.postalCode")
  83. private TextField address_postalCode = new TextField("Postal code");
  84. @PropertyId("address.city")
  85. private TextField address_city = new TextField("City");
  86. @PropertyId("address.country")
  87. private TextField address_country = new TextField("Country");
  88. public CustomForm() {
  89. fieldGroup.bindMemberFields(this);
  90. address_postalCode.setNullRepresentation("");
  91. gender.setNullRepresentation("");
  92. age.setNullRepresentation("");
  93. address_country.setNullRepresentation("");
  94. // Last name editing is disabled through property readonly.
  95. // Postal code editing is disabled through disabling field.
  96. /*
  97. * Currently only sets the initial state because of
  98. * https://dev.vaadin.com/ticket/17847
  99. *
  100. * Must set lastName state initially as BeanFieldGroup can't tell it
  101. * should be read-only before setting an item data source
  102. */
  103. lastName.setReadOnly(true);
  104. address_postalCode.setEnabled(false);
  105. birthDate.setNullRepresentation("");
  106. age.addValidator(new IntegerRangeValidator(
  107. "Must be between 0 and 100", 0, 100));
  108. setDefaultComponentAlignment(Alignment.MIDDLE_LEFT);
  109. addComponents(firstName, lastName, gender, birthDate, age, alive,
  110. address_streetAddress, address_postalCode, address_city,
  111. address_country);
  112. errorLabel.addStyleName(ValoTheme.LABEL_COLORED);
  113. setRows(3);
  114. addComponent(errorLabel, 0, 2, getColumns() - 1, 2);
  115. HorizontalLayout hl = new HorizontalLayout(save, cancel);
  116. hl.setSpacing(true);
  117. addComponent(hl);
  118. }
  119. @Override
  120. protected void handleCommitException(CommitException e) {
  121. String message = "";
  122. // Produce error message in the order in which the fields are in the
  123. // layout
  124. for (Component c : this) {
  125. if (!(c instanceof Field)) {
  126. continue;
  127. }
  128. Field<?> f = (Field<?>) c;
  129. Map<Field<?>, InvalidValueException> exceptions = e
  130. .getInvalidFields();
  131. if (exceptions.containsKey(f)) {
  132. message += f.getCaption() + ": "
  133. + exceptions.get(f).getLocalizedMessage()
  134. + "<br/>\n";
  135. }
  136. }
  137. errorLabel.setValue(message);
  138. }
  139. @Override
  140. protected void discard() {
  141. super.discard();
  142. errorLabel.setValue(null);
  143. }
  144. }
  145. protected abstract void deselectAll();
  146. public class AbstractForm extends GridLayout {
  147. protected Button save = new Button("Save");
  148. protected Button cancel = new Button("Cancel");
  149. protected BeanFieldGroup<ComplexPerson> fieldGroup = new BeanFieldGroup<ComplexPerson>(
  150. ComplexPerson.class) {
  151. @Override
  152. protected void configureField(com.vaadin.v7.ui.Field<?> field) {
  153. super.configureField(field);
  154. if (field.getCaption().equals("Postal code")) {
  155. // Last name editing is disabled through property.
  156. // Postal code editing is disabled through field.
  157. /*
  158. * This is needed because of
  159. * https://dev.vaadin.com/ticket/17847
  160. */
  161. field.setEnabled(false);
  162. }
  163. };
  164. };
  165. public AbstractForm() {
  166. super(5, 1);
  167. setSpacing(true);
  168. setId("form");
  169. save.addClickListener(event -> {
  170. try {
  171. fieldGroup.commit();
  172. log("Saved " + fieldGroup.getItemDataSource());
  173. } catch (CommitException e) {
  174. handleCommitException(e);
  175. log("Commit failed: " + e.getMessage());
  176. }
  177. });
  178. cancel.addClickListener(event -> {
  179. log("Discarded " + fieldGroup.getItemDataSource());
  180. discard();
  181. });
  182. }
  183. protected void discard() {
  184. deselectAll();
  185. }
  186. protected void handleCommitException(CommitException e) {
  187. String message = "";
  188. for (Object propertyId : e.getInvalidFields().keySet()) {
  189. Field<?> f = e.getFieldGroup().getField(propertyId);
  190. message += f.getCaption() + ": "
  191. + e.getInvalidFields().get(propertyId);
  192. }
  193. if (!message.isEmpty()) {
  194. Notification.show(message, Type.ERROR_MESSAGE);
  195. }
  196. }
  197. public void edit(BeanItem<ComplexPerson> item) {
  198. fieldGroup.setItemDataSource(item);
  199. }
  200. }
  201. public class AutoGeneratedForm extends AbstractForm {
  202. public AutoGeneratedForm(Class<? extends Field> class1) {
  203. for (String p : columns) {
  204. Field f = fieldGroup.getFieldFactory()
  205. .createField(container.getType(p), class1);
  206. f.setCaption(SharedUtil.propertyIdToHumanFriendly(p));
  207. fieldGroup.bind(f, p);
  208. addComponent(f);
  209. }
  210. HorizontalLayout hl = new HorizontalLayout(save, cancel);
  211. hl.setSpacing(true);
  212. addComponent(hl);
  213. }
  214. }
  215. }