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.

VForm.java 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*
  2. @ITMillApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.terminal.gwt.client.ui;
  5. import java.util.Set;
  6. import com.google.gwt.user.client.DOM;
  7. import com.google.gwt.user.client.Element;
  8. import com.google.gwt.user.client.ui.ComplexPanel;
  9. import com.google.gwt.user.client.ui.Widget;
  10. import com.vaadin.terminal.gwt.client.ApplicationConnection;
  11. import com.vaadin.terminal.gwt.client.BrowserInfo;
  12. import com.vaadin.terminal.gwt.client.Container;
  13. import com.vaadin.terminal.gwt.client.VErrorMessage;
  14. import com.vaadin.terminal.gwt.client.Paintable;
  15. import com.vaadin.terminal.gwt.client.RenderInformation;
  16. import com.vaadin.terminal.gwt.client.RenderSpace;
  17. import com.vaadin.terminal.gwt.client.UIDL;
  18. import com.vaadin.terminal.gwt.client.Util;
  19. public class VForm extends ComplexPanel implements Container {
  20. private String height = "";
  21. private String width = "";
  22. public static final String CLASSNAME = "i-form";
  23. private Container lo;
  24. private Element legend = DOM.createLegend();
  25. private Element caption = DOM.createSpan();
  26. private Element errorIndicatorElement = DOM.createDiv();
  27. private Element desc = DOM.createDiv();
  28. private Icon icon;
  29. private VErrorMessage errorMessage = new VErrorMessage();
  30. private Element fieldContainer = DOM.createDiv();
  31. private Element footerContainer = DOM.createDiv();
  32. private Element fieldSet = DOM.createFieldSet();
  33. private Container footer;
  34. private ApplicationConnection client;
  35. private RenderInformation renderInformation = new RenderInformation();
  36. private int borderPaddingHorizontal;
  37. private int borderPaddingVertical;
  38. private boolean rendering = false;
  39. public VForm() {
  40. setElement(DOM.createDiv());
  41. DOM.appendChild(getElement(), fieldSet);
  42. setStyleName(CLASSNAME);
  43. DOM.appendChild(fieldSet, legend);
  44. DOM.appendChild(legend, caption);
  45. DOM.setElementProperty(errorIndicatorElement, "className",
  46. "i-errorindicator");
  47. DOM.setStyleAttribute(errorIndicatorElement, "display", "none");
  48. DOM.setInnerText(errorIndicatorElement, " "); // needed for IE
  49. DOM.setElementProperty(desc, "className", "i-form-description");
  50. DOM.appendChild(fieldSet, desc);
  51. DOM.appendChild(fieldSet, fieldContainer);
  52. errorMessage.setVisible(false);
  53. errorMessage.setStyleName(CLASSNAME + "-errormessage");
  54. DOM.appendChild(fieldSet, errorMessage.getElement());
  55. DOM.appendChild(fieldSet, footerContainer);
  56. }
  57. public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
  58. rendering = true;
  59. boolean measure = false;
  60. if (this.client == null) {
  61. this.client = client;
  62. measure = true;
  63. }
  64. if (client.updateComponent(this, uidl, false)) {
  65. rendering = false;
  66. return;
  67. }
  68. if (measure) {
  69. // Measure the border when the style names have been set
  70. borderPaddingVertical = getOffsetHeight();
  71. int ow = getOffsetWidth();
  72. int dow = desc.getOffsetWidth();
  73. borderPaddingHorizontal = ow - dow;
  74. }
  75. boolean legendEmpty = true;
  76. if (uidl.hasAttribute("caption")) {
  77. DOM.setInnerText(caption, uidl.getStringAttribute("caption"));
  78. legendEmpty = false;
  79. } else {
  80. DOM.setInnerText(caption, "");
  81. }
  82. if (uidl.hasAttribute("icon")) {
  83. if (icon == null) {
  84. icon = new Icon(client);
  85. DOM.insertChild(legend, icon.getElement(), 0);
  86. }
  87. icon.setUri(uidl.getStringAttribute("icon"));
  88. legendEmpty = false;
  89. } else {
  90. if (icon != null) {
  91. DOM.removeChild(legend, icon.getElement());
  92. }
  93. }
  94. if (legendEmpty) {
  95. DOM.setStyleAttribute(legend, "display", "none");
  96. } else {
  97. DOM.setStyleAttribute(legend, "display", "");
  98. }
  99. if (uidl.hasAttribute("error")) {
  100. final UIDL errorUidl = uidl.getErrors();
  101. errorMessage.updateFromUIDL(errorUidl);
  102. errorMessage.setVisible(true);
  103. } else {
  104. errorMessage.setVisible(false);
  105. }
  106. if (uidl.hasAttribute("description")) {
  107. DOM.setInnerHTML(desc, uidl.getStringAttribute("description"));
  108. } else {
  109. DOM.setInnerHTML(desc, "");
  110. }
  111. updateSize();
  112. // TODO Check if this is needed
  113. client.runDescendentsLayout(this);
  114. final UIDL layoutUidl = uidl.getChildUIDL(0);
  115. Container newLo = (Container) client.getPaintable(layoutUidl);
  116. if (lo == null) {
  117. lo = newLo;
  118. add((Widget) lo, fieldContainer);
  119. } else if (lo != newLo) {
  120. client.unregisterPaintable(lo);
  121. remove((Widget) lo);
  122. lo = newLo;
  123. add((Widget) lo, fieldContainer);
  124. }
  125. lo.updateFromUIDL(layoutUidl, client);
  126. if (uidl.getChildCount() > 1) {
  127. // render footer
  128. Container newFooter = (Container) client.getPaintable(uidl
  129. .getChildUIDL(1));
  130. if (footer == null) {
  131. add((Widget) newFooter, footerContainer);
  132. footer = newFooter;
  133. } else if (newFooter != footer) {
  134. remove((Widget) footer);
  135. client.unregisterPaintable(footer);
  136. add((Widget) newFooter, footerContainer);
  137. }
  138. footer = newFooter;
  139. footer.updateFromUIDL(uidl.getChildUIDL(1), client);
  140. } else {
  141. if (footer != null) {
  142. remove((Widget) footer);
  143. client.unregisterPaintable(footer);
  144. }
  145. }
  146. rendering = false;
  147. }
  148. public void updateSize() {
  149. renderInformation.updateSize(getElement());
  150. renderInformation.setContentAreaHeight(renderInformation
  151. .getRenderedSize().getHeight()
  152. - borderPaddingVertical);
  153. if (BrowserInfo.get().isIE6()) {
  154. getElement().getStyle().setProperty("overflow", "hidden");
  155. }
  156. renderInformation.setContentAreaWidth(renderInformation
  157. .getRenderedSize().getWidth()
  158. - borderPaddingHorizontal);
  159. }
  160. public RenderSpace getAllocatedSpace(Widget child) {
  161. if (child == lo) {
  162. int hPixels = 0;
  163. if (!"".equals(height)) {
  164. hPixels = getOffsetHeight();
  165. hPixels -= borderPaddingVertical;
  166. hPixels -= footerContainer.getOffsetHeight();
  167. hPixels -= errorMessage.getOffsetHeight();
  168. hPixels -= desc.getOffsetHeight();
  169. }
  170. return new RenderSpace(renderInformation.getContentAreaSize()
  171. .getWidth(), hPixels);
  172. } else if (child == footer) {
  173. return new RenderSpace(footerContainer.getOffsetWidth(), 0);
  174. } else {
  175. ApplicationConnection.getConsole().error(
  176. "Invalid child requested RenderSpace information");
  177. return null;
  178. }
  179. }
  180. public boolean hasChildComponent(Widget component) {
  181. return component != null && (component == lo || component == footer);
  182. }
  183. public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
  184. if (!hasChildComponent(oldComponent)) {
  185. throw new IllegalArgumentException(
  186. "Old component is not inside this Container");
  187. }
  188. remove(oldComponent);
  189. if (oldComponent == lo) {
  190. lo = (Container) newComponent;
  191. add((Widget) lo, fieldContainer);
  192. } else {
  193. footer = (Container) newComponent;
  194. add((Widget) footer, footerContainer);
  195. }
  196. }
  197. public boolean requestLayout(Set<Paintable> child) {
  198. if (height != null && width != null) {
  199. /*
  200. * If the height and width has been specified the child components
  201. * cannot make the size of the layout change
  202. */
  203. return true;
  204. }
  205. if (renderInformation.updateSize(getElement())) {
  206. return false;
  207. } else {
  208. return true;
  209. }
  210. }
  211. public void updateCaption(Paintable component, UIDL uidl) {
  212. // NOP form don't render caption for neither field layout nor footer
  213. // layout
  214. }
  215. @Override
  216. public void setHeight(String height) {
  217. if (this.height.equals(height)) {
  218. return;
  219. }
  220. this.height = height;
  221. super.setHeight(height);
  222. updateSize();
  223. }
  224. @Override
  225. public void setWidth(String width) {
  226. if (Util.equals(this.width, width)) {
  227. return;
  228. }
  229. this.width = width;
  230. super.setWidth(width);
  231. updateSize();
  232. if (!rendering && height.equals("")) {
  233. // Width might affect height
  234. Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this);
  235. }
  236. }
  237. }