Fix for issue 1112 (Add InsertPanel interface)
Review: http://gwt-code-reviews.appspot.com/57808
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@6070 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/AbsolutePanel.java b/user/src/com/google/gwt/user/client/ui/AbsolutePanel.java
index 188dc6a..0cd3fc1 100644
--- a/user/src/com/google/gwt/user/client/ui/AbsolutePanel.java
+++ b/user/src/com/google/gwt/user/client/ui/AbsolutePanel.java
@@ -34,7 +34,7 @@
* the widget may be modified by the panel.
* </p>
*/
-public class AbsolutePanel extends ComplexPanel {
+public class AbsolutePanel extends ComplexPanel implements InsertPanel {
/**
* Changes a DOM element's positioning to static.
@@ -70,11 +70,6 @@
setElement(elem);
}
- /**
- * Adds a child widget to this panel.
- *
- * @param w the child widget to be added
- */
@Override
public void add(Widget w) {
super.add(w, getElement());
@@ -95,8 +90,9 @@
// The Widget should be removed from its parent before any positional
// changes are made to prevent flickering.
w.removeFromParent();
+ int beforeIndex = getWidgetCount();
setWidgetPositionImpl(w, left, top);
- add(w);
+ insert(w, beforeIndex);
}
/**
@@ -125,6 +121,33 @@
- DOM.getAbsoluteTop(getElement());
}
+ public void insert(Widget w, int beforeIndex) {
+ insert(w, getElement(), beforeIndex, true);
+ }
+
+ /**
+ * Inserts a child widget at the specified position before the specified
+ * index. Setting a position of <code>(-1, -1)</code> will cause the child
+ * widget to be positioned statically. If the widget is already a child of
+ * this panel, it will be moved to the specified index.
+ *
+ * @param w the child widget to be inserted
+ * @param left the widget's left position
+ * @param top the widget's top position
+ * @param beforeIndex the index before which it will be inserted
+ * @throws IndexOutOfBoundsException if <code>beforeIndex</code> is out of
+ * range
+ */
+ public void insert(Widget w, int left, int top, int beforeIndex) {
+ // In order to avoid the potential for a flicker effect, it is necessary
+ // to set the position of the widget before adding it to the AbsolutePanel.
+ // The Widget should be removed from its parent before any positional
+ // changes are made to prevent flickering.
+ w.removeFromParent();
+ setWidgetPositionImpl(w, left, top);
+ insert(w, beforeIndex);
+ }
+
/**
* Overrides {@link ComplexPanel#remove(Widget)} to change the removed
* Widget's element back to static positioning.This is done so that any
diff --git a/user/src/com/google/gwt/user/client/ui/DeckPanel.java b/user/src/com/google/gwt/user/client/ui/DeckPanel.java
index 8ce725d..0126171 100644
--- a/user/src/com/google/gwt/user/client/ui/DeckPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/DeckPanel.java
@@ -31,7 +31,7 @@
* cleared.
* </p>
*/
-public class DeckPanel extends ComplexPanel implements HasAnimation {
+public class DeckPanel extends ComplexPanel implements HasAnimation, InsertPanel {
/**
* The duration of the animation.
*/
@@ -244,11 +244,6 @@
setElement(DOM.createDiv());
}
- /**
- * Adds the specified widget to the deck.
- *
- * @param w the widget to be added
- */
@Override
public void add(Widget w) {
Element container = createWidgetContainer();
@@ -276,14 +271,6 @@
return getWidgetIndex(visibleWidget);
}
- /**
- * Inserts a widget before the specified index.
- *
- * @param w the widget to be inserted
- * @param beforeIndex the index before which it will be inserted
- * @throws IndexOutOfBoundsException if <code>beforeIndex</code> is out of
- * range
- */
public void insert(Widget w, int beforeIndex) {
Element container = createWidgetContainer();
DOM.insertChild(getElement(), container, beforeIndex);
diff --git a/user/src/com/google/gwt/user/client/ui/FlowPanel.java b/user/src/com/google/gwt/user/client/ui/FlowPanel.java
index 9da634d..d27c74c 100644
--- a/user/src/com/google/gwt/user/client/ui/FlowPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/FlowPanel.java
@@ -26,7 +26,7 @@
* <img class='gallery' src='FlowPanel.png'/>
* </p>
*/
-public class FlowPanel extends ComplexPanel {
+public class FlowPanel extends ComplexPanel implements InsertPanel {
/**
* Creates an empty flow panel.
diff --git a/user/src/com/google/gwt/user/client/ui/HorizontalPanel.java b/user/src/com/google/gwt/user/client/ui/HorizontalPanel.java
index 21b555a..8071ce6 100644
--- a/user/src/com/google/gwt/user/client/ui/HorizontalPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/HorizontalPanel.java
@@ -25,7 +25,8 @@
* <img class='gallery' src='HorizontalPanel.png'/>
* </p>
*/
-public class HorizontalPanel extends CellPanel implements HasAlignment {
+public class HorizontalPanel extends CellPanel implements HasAlignment,
+ InsertPanel {
private HorizontalAlignmentConstant horzAlign = ALIGN_DEFAULT;
private Element tableRow;
@@ -42,12 +43,6 @@
DOM.setElementProperty(getTable(), "cellPadding", "0");
}
- /**
- * Adds a child widget to the panel. If the Widget is already attached to the
- * HorizontalPanel, it will be moved to the end of the panel.
- *
- * @param w the widget to be added
- */
@Override
public void add(Widget w) {
Element td = createAlignedTd();
@@ -63,15 +58,6 @@
return vertAlign;
}
- /**
- * Inserts a widget before the specified index. If the Widget is already
- * attached to the HorizontalPanel, it will be moved to the specified index.
- *
- * @param w the widget to be inserted
- * @param beforeIndex the index before which it will be inserted
- * @throws IndexOutOfBoundsException if <code>beforeIndex</code> is out of
- * range
- */
public void insert(Widget w, int beforeIndex) {
checkIndexBoundsForInsertion(beforeIndex);
diff --git a/user/src/com/google/gwt/user/client/ui/StackPanel.java b/user/src/com/google/gwt/user/client/ui/StackPanel.java
index feb0cc7..64b49ef 100644
--- a/user/src/com/google/gwt/user/client/ui/StackPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/StackPanel.java
@@ -38,7 +38,7 @@
* {@example com.google.gwt.examples.StackPanelExample}
* </p>
*/
-public class StackPanel extends ComplexPanel {
+public class StackPanel extends ComplexPanel implements InsertPanel {
private static final String DEFAULT_STYLENAME = "gwt-StackPanel";
private static final String DEFAULT_ITEM_STYLENAME = DEFAULT_STYLENAME
+ "Item";
@@ -62,11 +62,6 @@
setStyleName(DEFAULT_STYLENAME);
}
- /**
- * Adds a new child with the given widget.
- *
- * @param w the widget to be added
- */
@Override
public void add(Widget w) {
insert(w, getWidgetCount());
@@ -104,14 +99,6 @@
return visibleStack;
}
- /**
- * Inserts a widget before the specified index.
- *
- * @param w the widget to be inserted
- * @param beforeIndex the index before which it will be inserted
- * @throws IndexOutOfBoundsException if <code>beforeIndex</code> is out of
- * range
- */
public void insert(Widget w, int beforeIndex) {
// header
Element trh = DOM.createTR();
diff --git a/user/src/com/google/gwt/user/client/ui/VerticalPanel.java b/user/src/com/google/gwt/user/client/ui/VerticalPanel.java
index f9bacd2..2bf33e8 100644
--- a/user/src/com/google/gwt/user/client/ui/VerticalPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/VerticalPanel.java
@@ -25,7 +25,8 @@
* <img class='gallery' src='VerticalPanel.png'/>
* </p>
*/
-public class VerticalPanel extends CellPanel implements HasAlignment {
+public class VerticalPanel extends CellPanel implements HasAlignment,
+ InsertPanel {
private HorizontalAlignmentConstant horzAlign = ALIGN_DEFAULT;
private VerticalAlignmentConstant vertAlign = ALIGN_TOP;
@@ -38,12 +39,6 @@
DOM.setElementProperty(getTable(), "cellPadding", "0");
}
- /**
- * Adds a child widget to the panel. If the Widget is already attached to the
- * VerticalPanel, it will be moved to the end of the panel.
- *
- * @param w the widget to be added
- */
@Override
public void add(Widget w) {
Element tr = DOM.createTR();
@@ -61,21 +56,13 @@
return vertAlign;
}
- /**
- * Inserts a widget before the specified index. If the Widget is already
- * attached to the VerticalPanel, it will be moved to the specified index.
- *
- * @param w the widget to be inserted
- * @param beforeIndex the index before which it will be inserted
- * @throws IndexOutOfBoundsException if <code>beforeIndex</code> is out of
- * range
- */
public void insert(Widget w, int beforeIndex) {
checkIndexBoundsForInsertion(beforeIndex);
Element tr = DOM.createTR();
Element td = createAlignedTd();
DOM.appendChild(tr, td);
+
/*
* The case where we reinsert an already existing child is tricky.
*
diff --git a/user/test/com/google/gwt/user/client/ui/AbsolutePanelTest.java b/user/test/com/google/gwt/user/client/ui/AbsolutePanelTest.java
index ff5879c..0d2da55 100644
--- a/user/test/com/google/gwt/user/client/ui/AbsolutePanelTest.java
+++ b/user/test/com/google/gwt/user/client/ui/AbsolutePanelTest.java
@@ -22,7 +22,7 @@
import com.google.gwt.user.client.Window;
/**
- * TODO: document me.
+ * Tests for {@link AbsolutePanel}.
*/
public class AbsolutePanelTest extends GWTTestCase {
@@ -34,6 +34,19 @@
HasWidgetsTester.testAll(new AbsolutePanel());
}
+ /**
+ * AbsolutePanel once had a bug where calling
+ * {@link AbsolutePanel#add(Widget, int, int)} twice on the same child widget
+ * would throw an {@link IndexOutOfBoundsException}.
+ */
+ public void testDoubleAdd() {
+ AbsolutePanel absolutePanel = new AbsolutePanel();
+ Label label = new Label("label");
+
+ absolutePanel.add(label, 10, 10);
+ absolutePanel.add(label, 10, 10);
+ }
+
@DoNotRunWith(Platform.Htmlunit)
public void testPositioning() {
// Make an absolute panel with a label at (3, 7).