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.

AbstractComponentContainer.java 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. @ITMillApache2LicenseForJavaFiles@
  3. */
  4. package com.itmill.toolkit.ui;
  5. import java.lang.reflect.Method;
  6. import java.util.Iterator;
  7. import java.util.LinkedList;
  8. /**
  9. * Extension to {@link AbstractComponent} that defines the default
  10. * implementation for the methods in {@link ComponentContainer}. Basic UI
  11. * components that need to contain other components inherit this class to easily
  12. * qualify as a component container.
  13. *
  14. * @author IT Mill Ltd
  15. * @version
  16. * @VERSION@
  17. * @since 3.0
  18. */
  19. public abstract class AbstractComponentContainer extends AbstractComponent
  20. implements ComponentContainer {
  21. /**
  22. * Constructs a new component container.
  23. */
  24. public AbstractComponentContainer() {
  25. super();
  26. }
  27. /**
  28. * Removes all components from the container. This should probably be
  29. * re-implemented in extending classes for a more powerful implementation.
  30. */
  31. public void removeAllComponents() {
  32. final LinkedList l = new LinkedList();
  33. // Adds all components
  34. for (final Iterator i = getComponentIterator(); i.hasNext();) {
  35. l.add(i.next());
  36. }
  37. // Removes all component
  38. for (final Iterator i = l.iterator(); i.hasNext();) {
  39. removeComponent((Component) i.next());
  40. }
  41. }
  42. /*
  43. * Moves all components from an another container into this container. Don't
  44. * add a JavaDoc comment here, we use the default documentation from
  45. * implemented interface.
  46. */
  47. public void moveComponentsFrom(ComponentContainer source) {
  48. final LinkedList components = new LinkedList();
  49. for (final Iterator i = source.getComponentIterator(); i.hasNext();) {
  50. components.add(i.next());
  51. }
  52. for (final Iterator i = components.iterator(); i.hasNext();) {
  53. final Component c = (Component) i.next();
  54. source.removeComponent(c);
  55. addComponent(c);
  56. }
  57. }
  58. /**
  59. * Notifies all contained components that the container is attached to a
  60. * window.
  61. *
  62. * @see com.itmill.toolkit.ui.Component#attach()
  63. */
  64. public void attach() {
  65. super.attach();
  66. for (final Iterator i = getComponentIterator(); i.hasNext();) {
  67. ((Component) i.next()).attach();
  68. }
  69. }
  70. /**
  71. * Notifies all contained components that the container is detached from a
  72. * window.
  73. *
  74. * @see com.itmill.toolkit.ui.Component#detach()
  75. */
  76. public void detach() {
  77. super.detach();
  78. for (final Iterator i = getComponentIterator(); i.hasNext();) {
  79. ((Component) i.next()).detach();
  80. }
  81. }
  82. /* Events */
  83. private static final Method COMPONENT_ATTACHED_METHOD;
  84. private static final Method COMPONENT_DETACHED_METHOD;
  85. static {
  86. try {
  87. COMPONENT_ATTACHED_METHOD = ComponentAttachListener.class
  88. .getDeclaredMethod("componentAttachedToContainer",
  89. new Class[] { ComponentAttachEvent.class });
  90. COMPONENT_DETACHED_METHOD = ComponentDetachListener.class
  91. .getDeclaredMethod("componentDetachedFromContainer",
  92. new Class[] { ComponentDetachEvent.class });
  93. } catch (final java.lang.NoSuchMethodException e) {
  94. // This should never happen
  95. throw new java.lang.RuntimeException(
  96. "Internal error finding methods in AbstractComponentContainer");
  97. }
  98. }
  99. /* documented in interface */
  100. public void addListener(ComponentAttachListener listener) {
  101. addListener(ComponentContainer.ComponentAttachEvent.class, listener,
  102. COMPONENT_ATTACHED_METHOD);
  103. }
  104. /* documented in interface */
  105. public void addListener(ComponentDetachListener listener) {
  106. addListener(ComponentContainer.ComponentDetachEvent.class, listener,
  107. COMPONENT_DETACHED_METHOD);
  108. }
  109. /* documented in interface */
  110. public void removeListener(ComponentAttachListener listener) {
  111. removeListener(ComponentContainer.ComponentAttachEvent.class, listener,
  112. COMPONENT_ATTACHED_METHOD);
  113. }
  114. /* documented in interface */
  115. public void removeListener(ComponentDetachListener listener) {
  116. removeListener(ComponentContainer.ComponentDetachEvent.class, listener,
  117. COMPONENT_DETACHED_METHOD);
  118. }
  119. /**
  120. * Fires the component attached event. This should be called by the
  121. * addComponent methods after the component have been added to this
  122. * container.
  123. *
  124. * @param component
  125. * the component that has been added to this container.
  126. */
  127. protected void fireComponentAttachEvent(Component component) {
  128. fireEvent(new ComponentAttachEvent(this, component));
  129. }
  130. /**
  131. * Fires the component detached event. This should be called by the
  132. * removeComponent methods after the component have been removed from this
  133. * container.
  134. *
  135. * @param component
  136. * the component that has been removed from this container.
  137. */
  138. protected void fireComponentDetachEvent(Component component) {
  139. fireEvent(new ComponentDetachEvent(this, component));
  140. }
  141. /**
  142. * This only implements the events and component parent calls. The extending
  143. * classes must implement component list maintenance and call this method
  144. * after component list maintenance.
  145. *
  146. * @see com.itmill.toolkit.ui.ComponentContainer#addComponent(Component)
  147. */
  148. public void addComponent(Component c) {
  149. if (c instanceof ComponentContainer) {
  150. // Make sure we're not adding the component inside it's own content
  151. for (Component parent = this; parent != null; parent = parent
  152. .getParent()) {
  153. if (parent == c) {
  154. throw new IllegalArgumentException(
  155. "Component cannot be added inside it's own content");
  156. }
  157. }
  158. }
  159. if (c.getParent() != null) {
  160. // If the component already has a parent, try to remove it
  161. ComponentContainer oldParent = (ComponentContainer) c.getParent();
  162. oldParent.removeComponent(c);
  163. }
  164. c.setParent(this);
  165. fireComponentAttachEvent(c);
  166. }
  167. /**
  168. * This only implements the events and component parent calls. The extending
  169. * classes must implement component list maintenance and call this method
  170. * before component list maintenance.
  171. *
  172. * @see com.itmill.toolkit.ui.ComponentContainer#removeComponent(Component)
  173. */
  174. public void removeComponent(Component c) {
  175. if (c.getParent() == this) {
  176. c.setParent(null);
  177. fireComponentDetachEvent(c);
  178. }
  179. }
  180. public void setEnabled(boolean enabled) {
  181. super.setEnabled(enabled);
  182. updateComponentDisabledState(!enabled);
  183. }
  184. public void setDisabledByContainer(boolean disabledByContainer) {
  185. super.setDisabledByContainer(disabledByContainer);
  186. updateComponentDisabledState(disabledByContainer);
  187. }
  188. private void updateComponentDisabledState(boolean disabled) {
  189. // Update the disabledByContainer state for all subcomponents
  190. for (Iterator i = getComponentIterator(); i.hasNext();) {
  191. Component c = (Component) i.next();
  192. if (c instanceof AbstractComponent) {
  193. ((AbstractComponent) c).setDisabledByContainer(disabled);
  194. }
  195. }
  196. }
  197. }