com.google.gwt.user.client.ui.ComplexPanel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vaadin-client Show documentation
Show all versions of vaadin-client Show documentation
Vaadin is a web application framework for Rich Internet Applications (RIA).
Vaadin enables easy development and maintenance of fast and
secure rich web
applications with a stunning look and feel and a wide browser support.
It features a server-side architecture with the majority of the logic
running
on the server. Ajax technology is used at the browser-side to ensure a
rich
and interactive user experience.
/*
* Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.user.client.ui;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.DOM;
import java.util.Iterator;
/**
* Abstract base class for panels that can contain multiple child widgets.
*/
public abstract class ComplexPanel extends Panel implements IndexedPanel.ForIsWidget {
private WidgetCollection children = new WidgetCollection(this);
/**
* The command used to orphan children.
*/
private AttachDetachException.Command orphanCommand;
public Widget getWidget(int index) {
return getChildren().get(index);
}
public int getWidgetCount() {
return getChildren().size();
}
public int getWidgetIndex(Widget child) {
return getChildren().indexOf(child);
}
public int getWidgetIndex(IsWidget child) {
return getWidgetIndex(asWidgetOrNull(child));
}
public Iterator iterator() {
return getChildren().iterator();
}
public boolean remove(int index) {
return remove(getWidget(index));
}
@Override
public boolean remove(Widget w) {
// Validate.
if (w.getParent() != this) {
return false;
}
// Orphan.
try {
orphan(w);
} finally {
// Physical detach.
Element elem = w.getElement();
DOM.getParent(elem).removeChild(elem);
// Logical detach.
getChildren().remove(w);
}
return true;
}
/**
* Adds a new child widget to the panel, attaching its Element to the
* specified container Element.
*
* @param child the child widget to be added
* @param container the element within which the child will be contained
*/
protected void add(Widget child, Element container) {
add(child, DOM.asOld(container));
}
/**
* @deprecated Call and override {@link #add(Widget, Element)} instead.
*/
@Deprecated
protected void add(Widget child, com.google.gwt.user.client.Element container) {
// Detach new child.
child.removeFromParent();
// Logical attach.
getChildren().add(child);
// Physical attach.
DOM.appendChild(container, child.getElement());
// Adopt.
adopt(child);
}
/**
* Adjusts beforeIndex to account for the possibility that the given widget is
* already a child of this panel.
*
* @param child the widget that might be an existing child
* @param beforeIndex the index at which it will be added to this panel
* @return the modified index
*/
protected int adjustIndex(Widget child, int beforeIndex) {
checkIndexBoundsForInsertion(beforeIndex);
// Check to see if this widget is already a direct child.
if (child.getParent() == this) {
// If the Widget's previous position was left of the desired new position
// shift the desired position left to reflect the removal
int idx = getWidgetIndex(child);
if (idx < beforeIndex) {
beforeIndex--;
}
}
return beforeIndex;
}
/**
* Checks that index
is in the range [0, getWidgetCount()), which
* is the valid range on accessible indexes.
*
* @param index the index being accessed
*/
protected void checkIndexBoundsForAccess(int index) {
if (index < 0 || index >= getWidgetCount()) {
throw new IndexOutOfBoundsException();
}
}
/**
* Checks that index
is in the range [0, getWidgetCount()], which
* is the valid range for indexes on an insertion.
*
* @param index the index where insertion will occur
*/
protected void checkIndexBoundsForInsertion(int index) {
if (index < 0 || index > getWidgetCount()) {
throw new IndexOutOfBoundsException();
}
}
/**
* Gets the list of children contained in this panel.
*
* @return a collection of child widgets
*/
protected WidgetCollection getChildren() {
return children;
}
/**
* Insert a new child Widget into this Panel at a specified index, attaching
* its Element to the specified container Element. The child Element will
* either be attached to the container at the same index, or simply appended
* to the container, depending on the value of domInsert
.
*
* @param child the child Widget to be added
* @param container the Element within which child
will be
* contained
* @param beforeIndex the index before which child
will be
* inserted
* @param domInsert if true
, insert child
into
* container
at beforeIndex
; otherwise
* append child
to the end of container
.
*/
protected void insert(Widget child, Element container, int beforeIndex,
boolean domInsert) {
insert(child, DOM.asOld(container), beforeIndex, domInsert);
}
/**
* @deprecated Call and override {@link insert(Widget, Element, int, boolean)} instead.
*/
@Deprecated
protected void insert(Widget child, com.google.gwt.user.client.Element container,
int beforeIndex, boolean domInsert) {
// Validate index; adjust if the widget is already a child of this panel.
beforeIndex = adjustIndex(child, beforeIndex);
// Detach new child.
child.removeFromParent();
// Logical attach.
getChildren().insert(child, beforeIndex);
// Physical attach.
if (domInsert) {
DOM.insertChild(container, child.getElement(), beforeIndex);
} else {
DOM.appendChild(container, child.getElement());
}
// Adopt.
adopt(child);
}
void doLogicalClear() {
// TODO(jgw): When Layout work has landed, deprecate FlowPanel (the only
// caller of this method in our code), and deprecate this method with an eye
// to making it private down the road.
// Only use one orphan command per panel to avoid object creation.
if (orphanCommand == null) {
orphanCommand = new AttachDetachException.Command() {
public void execute(Widget w) {
orphan(w);
}
};
}
try {
AttachDetachException.tryCommand(this, orphanCommand);
} finally {
children = new WidgetCollection(this);
}
}
}