diff options
author | Henri Sara <henri.sara@itmill.com> | 2009-05-11 09:19:03 +0000 |
---|---|---|
committer | Henri Sara <henri.sara@itmill.com> | 2009-05-11 09:19:03 +0000 |
commit | adc8c0ad3573272c236040c3a76005b9e73a5737 (patch) | |
tree | a3860704dbd5b82dc6af38684b80f8ef79a32722 /src/com/vaadin/ui/AbstractComponentContainer.java | |
parent | 5abc870dda584d0c2fc47fd5eec4ae3de3fa240e (diff) | |
download | vaadin-framework-adc8c0ad3573272c236040c3a76005b9e73a5737.tar.gz vaadin-framework-adc8c0ad3573272c236040c3a76005b9e73a5737.zip |
#2904: initial bulk rename "com.itmill.toolkit" -> "com.vaadin"
- com.itmill.toolkit.external not yet fully renamed
svn changeset:7715/svn branch:6.0
Diffstat (limited to 'src/com/vaadin/ui/AbstractComponentContainer.java')
-rw-r--r-- | src/com/vaadin/ui/AbstractComponentContainer.java | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/src/com/vaadin/ui/AbstractComponentContainer.java b/src/com/vaadin/ui/AbstractComponentContainer.java new file mode 100644 index 0000000000..517dff14ac --- /dev/null +++ b/src/com/vaadin/ui/AbstractComponentContainer.java @@ -0,0 +1,274 @@ +/* +@ITMillApache2LicenseForJavaFiles@ + */ + +package com.vaadin.ui; + +import java.lang.reflect.Method; +import java.util.Iterator; +import java.util.LinkedList; + +/** + * Extension to {@link AbstractComponent} that defines the default + * implementation for the methods in {@link ComponentContainer}. Basic UI + * components that need to contain other components inherit this class to easily + * qualify as a component container. + * + * @author IT Mill Ltd + * @version + * @VERSION@ + * @since 3.0 + */ +@SuppressWarnings("serial") +public abstract class AbstractComponentContainer extends AbstractComponent + implements ComponentContainer { + + /** + * Constructs a new component container. + */ + public AbstractComponentContainer() { + super(); + } + + /** + * Removes all components from the container. This should probably be + * re-implemented in extending classes for a more powerful implementation. + */ + public void removeAllComponents() { + final LinkedList l = new LinkedList(); + + // Adds all components + for (final Iterator i = getComponentIterator(); i.hasNext();) { + l.add(i.next()); + } + + // Removes all component + for (final Iterator i = l.iterator(); i.hasNext();) { + removeComponent((Component) i.next()); + } + } + + /* + * Moves all components from an another container into this container. Don't + * add a JavaDoc comment here, we use the default documentation from + * implemented interface. + */ + public void moveComponentsFrom(ComponentContainer source) { + final LinkedList components = new LinkedList(); + for (final Iterator i = source.getComponentIterator(); i.hasNext();) { + components.add(i.next()); + } + + for (final Iterator i = components.iterator(); i.hasNext();) { + final Component c = (Component) i.next(); + source.removeComponent(c); + addComponent(c); + } + } + + /** + * Notifies all contained components that the container is attached to a + * window. + * + * @see com.vaadin.ui.Component#attach() + */ + @Override + public void attach() { + super.attach(); + + for (final Iterator i = getComponentIterator(); i.hasNext();) { + ((Component) i.next()).attach(); + } + } + + /** + * Notifies all contained components that the container is detached from a + * window. + * + * @see com.vaadin.ui.Component#detach() + */ + @Override + public void detach() { + super.detach(); + + for (final Iterator i = getComponentIterator(); i.hasNext();) { + ((Component) i.next()).detach(); + } + } + + /* Events */ + + private static final Method COMPONENT_ATTACHED_METHOD; + + private static final Method COMPONENT_DETACHED_METHOD; + + static { + try { + COMPONENT_ATTACHED_METHOD = ComponentAttachListener.class + .getDeclaredMethod("componentAttachedToContainer", + new Class[] { ComponentAttachEvent.class }); + COMPONENT_DETACHED_METHOD = ComponentDetachListener.class + .getDeclaredMethod("componentDetachedFromContainer", + new Class[] { ComponentDetachEvent.class }); + } catch (final java.lang.NoSuchMethodException e) { + // This should never happen + throw new java.lang.RuntimeException( + "Internal error finding methods in AbstractComponentContainer"); + } + } + + /* documented in interface */ + public void addListener(ComponentAttachListener listener) { + addListener(ComponentContainer.ComponentAttachEvent.class, listener, + COMPONENT_ATTACHED_METHOD); + } + + /* documented in interface */ + public void addListener(ComponentDetachListener listener) { + addListener(ComponentContainer.ComponentDetachEvent.class, listener, + COMPONENT_DETACHED_METHOD); + } + + /* documented in interface */ + public void removeListener(ComponentAttachListener listener) { + removeListener(ComponentContainer.ComponentAttachEvent.class, listener, + COMPONENT_ATTACHED_METHOD); + } + + /* documented in interface */ + public void removeListener(ComponentDetachListener listener) { + removeListener(ComponentContainer.ComponentDetachEvent.class, listener, + COMPONENT_DETACHED_METHOD); + } + + /** + * Fires the component attached event. This should be called by the + * addComponent methods after the component have been added to this + * container. + * + * @param component + * the component that has been added to this container. + */ + protected void fireComponentAttachEvent(Component component) { + fireEvent(new ComponentAttachEvent(this, component)); + } + + /** + * Fires the component detached event. This should be called by the + * removeComponent methods after the component have been removed from this + * container. + * + * @param component + * the component that has been removed from this container. + */ + protected void fireComponentDetachEvent(Component component) { + fireEvent(new ComponentDetachEvent(this, component)); + } + + /** + * This only implements the events and component parent calls. The extending + * classes must implement component list maintenance and call this method + * after component list maintenance. + * + * @see com.vaadin.ui.ComponentContainer#addComponent(Component) + */ + public void addComponent(Component c) { + if (c instanceof ComponentContainer) { + // Make sure we're not adding the component inside it's own content + for (Component parent = this; parent != null; parent = parent + .getParent()) { + if (parent == c) { + throw new IllegalArgumentException( + "Component cannot be added inside it's own content"); + } + } + } + + if (c.getParent() != null) { + // If the component already has a parent, try to remove it + ComponentContainer oldParent = (ComponentContainer) c.getParent(); + oldParent.removeComponent(c); + + } + + c.setParent(this); + fireComponentAttachEvent(c); + } + + /** + * This only implements the events and component parent calls. The extending + * classes must implement component list maintenance and call this method + * before component list maintenance. + * + * @see com.vaadin.ui.ComponentContainer#removeComponent(Component) + */ + public void removeComponent(Component c) { + if (c.getParent() == this) { + c.setParent(null); + fireComponentDetachEvent(c); + } + } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + if (getParent() != null && !getParent().isEnabled()) { + // some ancestor still disabled, don't update children + return; + } else { + requestRepaintAll(); + } + } + + @Override + public void setWidth(float width, int unit) { + if (getWidth() < 0 && width >= 0) { + // width becoming defined -> relative width children currently + // painted undefined may become defined + // TODO could be optimized(subtree of only those components + // which have undefined height due this component), currently just + // repaints whole subtree + requestRepaintAll(); + } else if (getWidth() >= 0 && width < 0) { + requestRepaintAll(); + } + super.setWidth(width, unit); + } + + @Override + public void setHeight(float height, int unit) { + float currentHeight = getHeight(); + if (currentHeight < 0.0f && height >= 0.0f) { + // height becoming defined -> relative height childs currently + // painted undefined may become defined + // TODO this could be optimized (subtree of only those components + // which have undefined width due this component), currently just + // repaints whole + // subtree + requestRepaintAll(); + } else if (currentHeight >= 0 && height < 0) { + requestRepaintAll(); + } + super.setHeight(height, unit); + } + + public void requestRepaintAll() { + requestRepaint(); + for (Iterator childIterator = getComponentIterator(); childIterator + .hasNext();) { + Component c = (Component) childIterator.next(); + if (c instanceof Form) { + // Form has children in layout, but is not ComponentContainer + c.requestRepaint(); + ((Form) c).getLayout().requestRepaintAll(); + } else if (c instanceof Table) { + ((Table) c).requestRepaintAll(); + } else if (c instanceof ComponentContainer) { + ((ComponentContainer) c).requestRepaintAll(); + } else { + c.requestRepaint(); + } + } + } + +}
\ No newline at end of file |