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.

CustomField.java 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * Copyright 2000-2016 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.v7.ui;
  17. import java.io.Serializable;
  18. import java.util.Iterator;
  19. import com.vaadin.ui.Component;
  20. import com.vaadin.ui.HasComponents;
  21. import com.vaadin.v7.data.Property;
  22. /**
  23. * A {@link Field} whose UI content can be constructed by the user, enabling the
  24. * creation of e.g. form fields by composing Vaadin components. Customization of
  25. * both the visual presentation and the logic of the field is possible.
  26. *
  27. * Subclasses must implement {@link #getType()} and {@link #initContent()}.
  28. *
  29. * Most custom fields can simply compose a user interface that calls the methods
  30. * {@link #setInternalValue(Object)} and {@link #getInternalValue()} when
  31. * necessary.
  32. *
  33. * It is also possible to override {@link #validate()},
  34. * {@link #setInternalValue(Object)}, {@link #commit()},
  35. * {@link #setPropertyDataSource(Property)}, {@link #isEmpty()} and other logic
  36. * of the field. Methods overriding {@link #setInternalValue(Object)} should
  37. * also call the corresponding superclass method.
  38. *
  39. * @param <T>
  40. * field value type
  41. *
  42. * @since 7.0
  43. */
  44. @Deprecated
  45. public abstract class CustomField<T> extends AbstractField<T>
  46. implements HasComponents {
  47. /**
  48. * The root component implementing the custom component.
  49. */
  50. private Component root = null;
  51. /**
  52. * Constructs a new custom field.
  53. *
  54. * <p>
  55. * The component is implemented by wrapping the methods of the composition
  56. * root component given as parameter. The composition root must be set
  57. * before the component can be used.
  58. * </p>
  59. */
  60. public CustomField() {
  61. // expand horizontally by default
  62. setWidth(100, Unit.PERCENTAGE);
  63. }
  64. /**
  65. * Constructs the content and notifies it that the {@link CustomField} is
  66. * attached to a window.
  67. *
  68. * @see com.vaadin.ui.Component#attach()
  69. */
  70. @Override
  71. public void attach() {
  72. // First call super attach to notify all children (none if content has
  73. // not yet been created)
  74. super.attach();
  75. // If the content has not yet been created, create and attach it at
  76. // this point by calling getContent()
  77. getContent();
  78. }
  79. /**
  80. * Returns the content (UI) of the custom component.
  81. *
  82. * @return Component
  83. */
  84. protected Component getContent() {
  85. if (null == root) {
  86. root = initContent();
  87. root.setParent(this);
  88. }
  89. return root;
  90. }
  91. /**
  92. * Create the content component or layout for the field. Subclasses of
  93. * {@link CustomField} should implement this method.
  94. *
  95. * Note that this method is called when the CustomField is attached to a
  96. * layout or when {@link #getContent()} is called explicitly for the first
  97. * time. It is only called once for a {@link CustomField}.
  98. *
  99. * @return {@link Component} representing the UI of the CustomField
  100. */
  101. protected abstract Component initContent();
  102. // Size related methods
  103. // TODO might not be necessary to override but following the pattern from
  104. // AbstractComponentContainer
  105. @Override
  106. public void setHeight(float height, Unit unit) {
  107. super.setHeight(height, unit);
  108. markAsDirtyRecursive();
  109. }
  110. @Override
  111. public void setWidth(float width, Unit unit) {
  112. super.setWidth(width, unit);
  113. markAsDirtyRecursive();
  114. }
  115. // ComponentContainer methods
  116. private class ComponentIterator
  117. implements Iterator<Component>, Serializable {
  118. boolean first = root != null;
  119. @Override
  120. public boolean hasNext() {
  121. return first;
  122. }
  123. @Override
  124. public Component next() {
  125. first = false;
  126. return getContent();
  127. }
  128. @Override
  129. public void remove() {
  130. throw new UnsupportedOperationException();
  131. }
  132. }
  133. @Override
  134. public Iterator<Component> iterator() {
  135. return new ComponentIterator();
  136. }
  137. /**
  138. * Sets the component to which all methods from the {@link Focusable}
  139. * interface should be delegated.
  140. * <p>
  141. * Set this to a wrapped field to include that field in the tabbing order,
  142. * to make it receive focus when {@link #focus()} is called and to make it
  143. * be correctly focused when used as a Grid editor component.
  144. * <p>
  145. * By default, {@link Focusable} events are handled by the super class and
  146. * ultimately ignored.
  147. *
  148. * @param focusDelegate
  149. * the focusable component to which focus events are redirected
  150. */
  151. public void setFocusDelegate(Focusable focusDelegate) {
  152. getState().focusDelegate = focusDelegate;
  153. }
  154. private Focusable getFocusable() {
  155. return (Focusable) getState(false).focusDelegate;
  156. }
  157. @Override
  158. public void focus() {
  159. if (getFocusable() != null) {
  160. getFocusable().focus();
  161. } else {
  162. super.focus();
  163. }
  164. }
  165. @Override
  166. public int getTabIndex() {
  167. if (getFocusable() != null) {
  168. return getFocusable().getTabIndex();
  169. } else {
  170. return super.getTabIndex();
  171. }
  172. }
  173. @Override
  174. public void setTabIndex(int tabIndex) {
  175. if (getFocusable() != null) {
  176. getFocusable().setTabIndex(tabIndex);
  177. } else {
  178. super.setTabIndex(tabIndex);
  179. }
  180. }
  181. }