001: /*
002: * MyGWT Widget Library
003: * Copyright(c) 2007, MyGWT.
004: * licensing@mygwt.net
005: *
006: * http://mygwt.net/license
007: */
008: package net.mygwt.ui.client.widget;
009:
010: import java.util.ArrayList;
011: import java.util.Iterator;
012: import java.util.List;
013:
014: import com.google.gwt.user.client.DOM;
015: import com.google.gwt.user.client.Element;
016: import com.google.gwt.user.client.ui.Widget;
017: import com.google.gwt.user.client.ui.WidgetHelper;
018:
019: /**
020: * A <code>Component</code> that contains child widgets.
021: *
022: * <dt><b>CSS:</b></dt>
023: * <dd>.my-container (the container itself)</dd>
024: * </dl>
025: */
026: public abstract class Container extends Component {
027:
028: /**
029: * attachChildren specifies if the container's children should be attached and
030: * detached. Default value is <code>true</code>.
031: */
032: protected boolean attachChildren = true;
033:
034: /**
035: * The container's children.
036: */
037: protected List items;
038:
039: private boolean autoDispose;
040:
041: /**
042: * Creates a new container.
043: */
044: public Container() {
045: items = new ArrayList();
046: }
047:
048: public void dispose() {
049: int count = getWidgetCount();
050: for (int i = 0; i < count; i++) {
051: remove(getWidget(0));
052: }
053: super .dispose();
054: }
055:
056: /**
057: * Returns the widget whose element or child element matches the given
058: * element.
059: *
060: * @param elem the element
061: * @return the matching widget or <code>null</code> if no match
062: */
063: public Widget findWidget(Element elem) {
064: int count = getWidgetCount();
065: for (int i = 0; i < count; i++) {
066: Widget w = getWidget(i);
067: if (DOM.isOrHasChild(w.getElement(), elem)) {
068: return w;
069: }
070: }
071: return null;
072: }
073:
074: /**
075: * Returns the auto dispose state. When <code>true</code>, child widgets
076: * will be disposed when removed from the container. Default value is
077: * <code>false</code>.
078: *
079: * @return the auto dispose state
080: */
081: public boolean getAutoDispose() {
082: return autoDispose;
083: }
084:
085: /**
086: * Returns the widget at the specified index.
087: *
088: * @param index the index
089: * @return the widget
090: */
091: public Widget getWidget(int index) {
092: return (Widget) items.get(index);
093: }
094:
095: /**
096: * Returns the number of child widgets.
097: *
098: * @return the widget count
099: */
100: public int getWidgetCount() {
101: return items.size();
102: }
103:
104: /**
105: * Returns an iterator over the container's children.
106: *
107: * @return an iterator
108: */
109: public Iterator iterator() {
110: return items.iterator();
111: }
112:
113: /**
114: * Removes a widget from the container.
115: *
116: * @param widget the widget to remove
117: * @return <code>true</code> if the widget was removed
118: */
119: public boolean remove(Widget widget) {
120: // orphon
121: if (attachChildren) {
122: if (widget.getParent() != this ) {
123: return false;
124: }
125: orphan(widget);
126: }
127:
128: // physical remove
129: if (rendered) {
130: Element elem = widget.getElement();
131: Element parent = DOM.getParent(elem);
132: if (parent != null) {
133: DOM.removeChild(parent, elem);
134: }
135: }
136:
137: // logical remove
138: items.remove(widget);
139:
140: if (autoDispose && widget instanceof Component) {
141: ((Component) widget).dispose();
142: }
143: return true;
144: }
145:
146: /**
147: * Sets the auto dispose state. When <code>true</code>, the container will
148: * automatically dispose any child widget that is removed from it. Default
149: * value is <code>false</code>
150: *
151: * @param autoDispose the auto dispose state
152: */
153: public void setAutoDispose(boolean autoDispose) {
154: this .autoDispose = autoDispose;
155: }
156:
157: protected final void adopt(Widget child) {
158: assert (child.getParent() == null);
159: WidgetHelper.setParent(child, this );
160: }
161:
162: protected void doAttachChildren() {
163: if (attachChildren) {
164: for (Iterator it = items.iterator(); it.hasNext();) {
165: Widget child = (Widget) it.next();
166: WidgetHelper.doAttach(child);
167: }
168: }
169: }
170:
171: protected void doDetachChildren() {
172: if (attachChildren) {
173: for (Iterator it = items.iterator(); it.hasNext();) {
174: Widget child = (Widget) it.next();
175: WidgetHelper.doDetach(child);
176: }
177: }
178: }
179:
180: protected final void orphan(Widget child) {
181: assert (child.getParent() == this);
182: WidgetHelper.setParent(child, null);
183: }
184: }
|