Package net.mygwt.ui.client.widget

Source Code of net.mygwt.ui.client.widget.Container

/*
* MyGWT Widget Library
* Copyright(c) 2007, MyGWT.
* licensing@mygwt.net
*
* http://mygwt.net/license
*/
package net.mygwt.ui.client.widget;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.mygwt.ui.client.MyDOM;
import net.mygwt.ui.client.util.Size;
import net.mygwt.ui.client.widget.layout.FlowLayout;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.WidgetHelper;

/**
* A panel which lays out it's children using a layout manager.
*
* <dl>
* <dt><b>Events:</b></dt>
*
* <dd><b>BeforeAdd</b> : (widget, item, index)<br>
* <div>Fires before a widget is added or inserted. Listeners can set the
* <code>doit</code> field to <code>false</code> to cancel the action.</div>
* <ul>
* <li>widget : this</li>
* <li>item : the widget being added</li>
* <li>index : the index at which the widget will be added</li>
* </ul>
* </dd>
*
* <dd><b>BeforeRemove</b> : (widget, item)<br>
* <div>Fires before a widget is removed. Listeners can set the
* <code>doit</code> field to <code>false</code> to cancel the action.</div>
* <ul>
* <li>widget : this</li>
* <li>item : the widget being removed</li>
* </ul>
* </dd>
*
* <dd><b>Add</b> : (widget, item, index)<br>
* <div>Fires after a widget has been added or inserted.</div>
* <ul>
* <li>widget : this</li>
* <li>item : the widget that was added</li>
* <li>index : the index at which the item will be added</li>
* </ul>
* </dd>
*
* <dd><b>Remove</b> : (widget, item)<br>
* <div>Fires after a widget has been removed.</div>
* <ul>
* <li>widget : this</li>
* <li>item : the widget being removed</li>
* </ul>
* </dd>
*
* <dt><b>CSS:</b></dt>
* <dd>.my-container (the container itself)</dd>
* </dl>
*
* @see Layout
*/
public abstract class Container extends Component {

  /**
   * <code>true</code> to automatically layout container when it is resized.
   * Default value is <code>true</code>.
   */
  public boolean monitorResize = true;

  /**
   * attachChildren specifies if the container's children should be attached and
   * detached. Default value is <code>true</code>.
   */
  public boolean attachChildren = true;

  /**
   * disableLayout specifies if the container's layout is disabled. Default
   * value is <code>false</code>.
   */
  public boolean disableLayout = false;

  protected Size lastSize;
  protected List items;
  protected Layout layout;
  private Map layoutMap;

  /**
   * Creates a new container.
   */
  public Container() {
    items = new ArrayList();
  }

  /**
   * Removes the layout data for the specified widget.
   *
   * @param widget the widget
   */
  public void removeLayoutData(Widget widget) {
    if (layoutMap != null) {
      layoutMap.remove(widget);
    }
  }

  /**
   * Returns the widget's layout data.
   *
   * @param widget the widget
   * @return the layout data
   */
  public Object getLayoutData(Widget widget) {
    if (layoutMap == null) {
      return null;
    }
    return layoutMap.get(widget);
  }

  /**
   * Sets the layout data for the widget.
   *
   * @param widget the widget
   * @param layoutData the widget's layout data
   */
  public void setLayoutData(Widget widget, Object layoutData) {
    if (layoutMap == null) {
      layoutMap = new HashMap();
    }
    layoutMap.put(widget, layoutData);
  }

  /**
   * Removes all child widgets.
   */
  public void clear() {
    int size = getWidgetCount();
    for (int i = 0; i < size; i++) {
      Widget w = getWidget(0);
      remove(w);
    }
  }

  /**
   * Returns the layout which is associated with the container, or
   * <code>null</code> if one has not been set.
   *
   * @return the container's layout or <code>null</code>
   */
  public Layout getLayout() {
    return layout;
  }

  /**
   * Override this method to specify the element the container's children will
   * be inserted.
   *
   * @return the element to be used as the panel's container
   */
  public Element getLayoutTarget() {
    return getElement();
  }

  /**
   * Returns the widget at the specified index.
   *
   * @param index the index
   * @return the widget
   */
  public Widget getWidget(int index) {
    return (Widget) items.get(index);
  }

  /**
   * Returns the number of child widgets.
   *
   * @return the count
   */
  public int getWidgetCount() {
    return items.size();
  }

  /**
   * Returns an iterator over the container's child widgets.
   *
   * @return an iterator
   */
  public Iterator iterator() {
    return items.iterator();
  }

  /**
   * Asks the layout to lay out the container's children. If a layout has not
   * been set a <code>FlowLayout</code> will be used. If the size of the
   * container has not changed sinse the last time layout was called it will not
   * be execute. See {@link #layout(boolean)} to force the layout to execute.
   */
  public void layout() {
    if (disableLayout) {
      return;
    }
    if (layout == null) {
      layout = new FlowLayout();
    }
    onLayout();
  }

  /**
   * Asks the layout to lay out the container's children. If a layout has not
   * been set a <code>FlowLayout</code> will be used.
   *
   * @param force <code>true</code> to force the layout to execute
   */
  public void layout(boolean force) {
    if (force) {
      lastSize = null;
    }
    layout();
  }

  /**
   * Sets the container's layout.
   *
   * @param layout the new layout
   */
  public void setLayout(Layout layout) {
    this.layout = layout;
  }

  protected final void adopt(Widget child) {
    assert (child.getParent() == null);
    WidgetHelper.setParent(child, this);
  }

  protected void doAttachChildren() {
    if (attachChildren) {
      for (Iterator it = items.iterator(); it.hasNext();) {
        Widget child = (Widget) it.next();
        WidgetHelper.doAttach(child);
      }
    }
  }

  protected void doDetachChildren() {
    if (attachChildren) {
      for (Iterator it = items.iterator(); it.hasNext();) {
        Widget child = (Widget) it.next();
        WidgetHelper.doDetach(child);
      }
    }
  }

  protected void onLayout() {
    if (!isAttached()) {
      return;
    }

    if (getWidgetCount() > 0) {
      Size size = MyDOM.getSize(getLayoutTarget());
      int width = size.width;
      int height = size.height;
      if (lastSize != null) {
        if (lastSize.width == width && lastSize.height == height) {
          return;
        }
      }
      lastSize = new Size(width, height);
    }
    layout.layout(this);
  }

  protected void onResize(int width, int height) {
    if (monitorResize) {
      layout();
    }
  }

  protected final void orphan(Widget child) {
    assert (child.getParent() == this);
    WidgetHelper.setParent(child, null);
  }

  protected void onLoad() {
    super.onLoad();
    layout();
  }

  /**
   * Removes a widget from the container.
   *
   * @param w the widget to remove
   * @return <code>true</code> if the widget was removed
   */
  public boolean remove(Widget w) {
    if (attachChildren) {
      if (w.getParent() != this) {
        return false;
      }
      // Orphan.
      orphan(w);
    }

    if (rendered) {
      Element elem = w.getElement();
      Element parent = DOM.getParent(elem);
      if (parent != null) {
        DOM.removeChild(parent, elem);
      }
    }

    // Logical detach.
    items.remove(w);

    removeLayoutData(w);

    return true;
  }
}
TOP

Related Classes of net.mygwt.ui.client.widget.Container

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.