/* * Ext GWT - Ext for GWT * Copyright(c) 2007-2009, Ext JS, LLC. * licensing@extjs.com * * http://extjs.com/license */ package com.extjs.gxt.ui.client.widget; import com.extjs.gxt.ui.client.core.El; import com.extjs.gxt.ui.client.widget.layout.FlowLayout; import com.extjs.gxt.ui.client.widget.layout.LayoutData; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.Widget; /** * A <code>Container</code> that lays out its children using a * <code>Layout</code>. Layouts are responsible for connecting the child * components to the container. Layouts are very flexible as they can create any * internal element structure, inserting its child components at any location. * For example, a TableLayout lays out its children using HTML tables. * * <p/> * Many layouts support layout data which are configurable objects that provide * additional information to the layout. These objects can be passed when adding * and inserting child components into the container. Each layout will document * if and what layout data it supports. * </p> * * Code snippet: * * <pre> * LayoutContainer container = new LayoutContainer(); * container.add(new Button("Click Me")); * container.setSize(300, 300); * container.setBorders(true); * RootPanel.get().add(container); * </pre> * * {@link FlowLayout} is the the default layout and will be used if not a layout * is not specified. You must size/position containers unless they are in an * existing container that lays out its children.</p> * * <dl> * <dt><b>Events:</b></dt> * * <dd><b>AfterLayout</b> : ContainerEvent(container)<br> * <div>Fires when the widgets in this container are arranged by the associated * layout.</div> * <ul> * <li>container : this</li> * </ul> * </dd> * </dl> * * <dl> * <dt>Inherited Events:</dt> * <dd>ScrollContainer Scroll</dd> * <dd>Container BeforeAdd</dd> * <dd>Container Add</dd> * <dd>Container BeforeRemove</dd> * <dd>Container Remove</dd> * <dd>BoxComponent Move</dd> * <dd>BoxComponent Resize</dd> * <dd>Component Enable</dd> * <dd>Component Disable</dd> * <dd>Component BeforeHide</dd> * <dd>Component Hide</dd> * <dd>Component BeforeShow</dd> * <dd>Component Show</dd> * <dd>Component Attach</dd> * <dd>Component Detach</dd> * <dd>Component BeforeRender</dd> * <dd>Component Render</dd> * <dd>Component BrowserEvent</dd> * <dd>Component BeforeStateRestore</dd> * <dd>Component StateRestore</dd> * <dd>Component BeforeStateSave</dd> * <dd>Component SaveState</dd> * </dl> * * @see Layout */ public class LayoutContainer extends ScrollContainer<Component> { /** * Creates a new layout container. */ public LayoutContainer() { enableLayout = true; } /** * Creates a new layout container. * * @param layout the layout */ public LayoutContainer(Layout layout) { this(); setLayout(layout); } /** * Adds a widget to this Container. Fires the <i>BeforeAdd</i> event before * adding, then fires the <i>Add</i> event after the component has been added. * * @param widget the widget to add. If the widget is not a Component instance * it will be wrapped in a WidgetComponent */ public boolean add(Widget widget) { return insert(widget, getItemCount()); } /** * Adds a widget to this Container. Fires the <i>BeforeAdd</i> event before * adding, then fires the <i>Add</i> event after the component has been added. * * @param widget the widget to add. If the widget is not a Component instance * it will be wrapped in a WidgetComponent * @param layoutData the layout data */ public boolean add(Widget widget, LayoutData layoutData) { return insert(widget, getItemCount(), layoutData); } /** * Creates a new HTML instance and adds it to the container. Fires the * <i>BeforeAdd</i> event before adding, then fires the <i>Add</i> event after * the component has been added. * * @param text the html text * @return the new HTML instance */ public Html addText(String text) { Html html = new Html(text); if (add(html)) { return html; } else { return null; } } /** * Returns the widget component that wraps the given widget. * * @param widget the wrapped widget * @return the component or null */ public WidgetComponent findComponent(Widget widget) { for (Component c : getItems()) { if (c instanceof WidgetComponent) { WidgetComponent wc = (WidgetComponent) c; if (widget == wc.getWidget()) { return wc; } } } return null; } /** * 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 super.getLayout(); } /** * Override this method to specify the element to be used by the layout as the * container. Allows the container to be decorated. * * @return the element to be used as the panel's container */ public El getLayoutTarget() { return el(); } @Override public int getWindowResizeDelay() { return super.getWindowResizeDelay(); } /** * Inserts a widget into this Container at a specified index. Fires the * <i>BeforeAdd</i> event before inserting, then fires the <i>Add</i> event * after the component has been inserted. * * @param widget the widget to insert. If the widget is not a Component * instance it will be wrapped in a WidgetComponent * @param index the index at which the component will be inserted in */ public boolean insert(Widget widget, int index) { return super.insert(wrapWidget(widget), index); } /** * Inserts a widget into this Container at a specified index. Fires the * <i>BeforeAdd</i> event before inserting, then fires the <i>Add</i> event * after the component has been inserted. * * @param widget the widget to insert. If the widget is not a Component * instance it will be wrapped in a WidgetComponent * @param index the index at which the component will be inserted in * @param layoutData the component's layout data */ public boolean insert(Widget widget, int index, LayoutData layoutData) { Component component = wrapWidget(widget); if (layoutData != null) { component.setLayoutData(layoutData); } boolean added = super.insert(component, index); return added; } /** * Returns <code>true</code> if the layout will be executed when widgets are * added or removed. * * @return the layout on change state */ public boolean isLayoutOnChange() { return layoutOnChange; } @Override public boolean isMonitorWindowResize() { return super.isMonitorWindowResize(); } @Override public boolean layout() { return super.layout(); } @Override public boolean layout(boolean force) { return super.layout(force); } /** * Removes a component from this container. Fires the 'BeforeRemove' event * before removing, then fires the 'Remove' event after the component has been * removed. * * @param widget the widget to remove */ public boolean remove(Widget widget) { Component c = null; if (!(widget instanceof Component)) { c = findComponent(widget); } else { c = (Component) widget; } if (c == null) { return false; } return super.remove(c); } /** * Removes all of children from this container. */ public boolean removeAll() { return super.removeAll(); } /** * Sets the container's layout. * * @param layout the new layout */ public void setLayout(Layout layout) { super.setLayout(layout); } /** * Sets the component's layout data. * * @param component the component * @param layoutData the layout data */ public void setLayoutData(Component component, LayoutData layoutData) { ComponentHelper.setLayoutData(component, layoutData); } /** * Specifies if the container's layout should be called when widgets are added * or removed. Default value is <code>false</code>. * * @param layoutOnChange <code>true</code> to enable */ public void setLayoutOnChange(boolean layoutOnChange) { this.layoutOnChange = layoutOnChange; } @Override public void setMonitorWindowResize(boolean monitorWindowResize) { super.setMonitorWindowResize(monitorWindowResize); } @Override public void setWindowResizeDelay(int delay) { super.setWindowResizeDelay(delay); } protected void onRender(Element parent, int index) { super.onRender(parent, index); if (el() == null) { setElement(DOM.createDiv(), parent, index); } } }