Fix for issue #718; fixes problems that would occur when adding/inserting a child Widget into its own parent HorizontalPanel or VerticalPanel.
Found by: fredsa
Patch by: bobv
Review by: scottb, jgw
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1008 8db76d5a-ed1c-0410-87a9-c151d255dfc7
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 8498a0a..f7f99ba 100644
--- a/user/src/com/google/gwt/user/client/ui/HorizontalPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/HorizontalPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * 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
@@ -44,7 +44,8 @@
}
/**
- * Adds a child widget to the panel.
+ * 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
*/
@@ -73,7 +74,8 @@
}
/**
- * Inserts a widget before the specified index.
+ * 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
@@ -83,7 +85,18 @@
public void insert(Widget w, int beforeIndex) {
// Call this early to ensure that the table doesn't end up partially
// constructed when an exception is thrown from adopt().
- w.removeFromParent();
+ int idx = getWidgetIndex(w);
+ if (idx == -1) {
+ w.removeFromParent();
+ } else {
+ remove(w);
+
+ // If the Widget's previous position was left of the desired new position
+ // shift the desired position left to reflect the removal
+ if (idx < beforeIndex) {
+ beforeIndex--;
+ }
+ }
Element td = DOM.createTD();
DOM.insertChild(tableRow, td, beforeIndex);
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 107a5fa..947ccf2 100644
--- a/user/src/com/google/gwt/user/client/ui/VerticalPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/VerticalPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * 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
@@ -40,7 +40,8 @@
}
/**
- * Adds a child widget to the panel.
+ * 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
*/
@@ -69,7 +70,8 @@
}
/**
- * Inserts a widget before the specified index.
+ * 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
@@ -79,7 +81,18 @@
public void insert(Widget w, int beforeIndex) {
// Call this early to ensure that the table doesn't end up partially
// constructed when an exception is thrown from adopt().
- w.removeFromParent();
+ int idx = getWidgetIndex(w);
+ if (idx == -1) {
+ w.removeFromParent();
+ } else {
+ remove(w);
+
+ // If the Widget's previous position was left of the desired new position
+ // shift the desired position left to reflect the removal
+ if (idx < beforeIndex) {
+ beforeIndex--;
+ }
+ }
Element tr = DOM.createTR();
Element td = DOM.createTD();
diff --git a/user/test/com/google/gwt/user/client/ui/HorizontalPanelTest.java b/user/test/com/google/gwt/user/client/ui/HorizontalPanelTest.java
new file mode 100644
index 0000000..154d4f0
--- /dev/null
+++ b/user/test/com/google/gwt/user/client/ui/HorizontalPanelTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.junit.client.GWTTestCase;
+
+import java.util.Iterator;
+
+/**
+ * A test for {@link HorizontalPanel}.
+ */
+public class HorizontalPanelTest extends GWTTestCase {
+
+ public String getModuleName() {
+ return "com.google.gwt.user.User";
+ }
+
+ public void testInsertMultipleTimes() {
+ HorizontalPanel p = new HorizontalPanel();
+
+ TextBox tb = new TextBox();
+ p.add(tb);
+ p.add(tb);
+ p.add(tb);
+
+ assertEquals(1, p.getWidgetCount());
+ assertEquals(0, p.getWidgetIndex(tb));
+ Iterator i = p.iterator();
+ assertTrue(i.hasNext());
+ assertTrue(tb.equals(i.next()));
+ assertFalse(i.hasNext());
+
+ Label l = new Label();
+ p.add(l);
+ p.add(l);
+ p.add(l);
+ assertEquals(2, p.getWidgetCount());
+ assertEquals(0, p.getWidgetIndex(tb));
+ assertEquals(1, p.getWidgetIndex(l));
+
+ p.insert(l, 0);
+ assertEquals(2, p.getWidgetCount());
+ assertEquals(0, p.getWidgetIndex(l));
+ assertEquals(1, p.getWidgetIndex(tb));
+
+ p.insert(l, 1);
+ assertEquals(2, p.getWidgetCount());
+ assertEquals(0, p.getWidgetIndex(l));
+ assertEquals(1, p.getWidgetIndex(tb));
+
+ p.insert(l, 2);
+ assertEquals(2, p.getWidgetCount());
+ assertEquals(0, p.getWidgetIndex(tb));
+ assertEquals(1, p.getWidgetIndex(l));
+ }
+}
diff --git a/user/test/com/google/gwt/user/client/ui/VerticalPanelTest.java b/user/test/com/google/gwt/user/client/ui/VerticalPanelTest.java
new file mode 100644
index 0000000..7f424e9
--- /dev/null
+++ b/user/test/com/google/gwt/user/client/ui/VerticalPanelTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.junit.client.GWTTestCase;
+
+import java.util.Iterator;
+
+/**
+ * A test for {@link VerticalPanel}.
+ */
+public class VerticalPanelTest extends GWTTestCase {
+
+ public String getModuleName() {
+ return "com.google.gwt.user.User";
+ }
+
+ public void testInsertMultipleTimes() {
+ VerticalPanel p = new VerticalPanel();
+
+ TextBox tb = new TextBox();
+ p.add(tb);
+ p.add(tb);
+ p.add(tb);
+
+ assertEquals(1, p.getWidgetCount());
+ assertEquals(0, p.getWidgetIndex(tb));
+ Iterator i = p.iterator();
+ assertTrue(i.hasNext());
+ assertTrue(tb.equals(i.next()));
+ assertFalse(i.hasNext());
+
+ Label l = new Label();
+ p.add(l);
+ p.add(l);
+ p.add(l);
+ assertEquals(2, p.getWidgetCount());
+ assertEquals(0, p.getWidgetIndex(tb));
+ assertEquals(1, p.getWidgetIndex(l));
+
+ p.insert(l, 0);
+ assertEquals(2, p.getWidgetCount());
+ assertEquals(0, p.getWidgetIndex(l));
+ assertEquals(1, p.getWidgetIndex(tb));
+
+ p.insert(l, 1);
+ assertEquals(2, p.getWidgetCount());
+ assertEquals(0, p.getWidgetIndex(l));
+ assertEquals(1, p.getWidgetIndex(tb));
+
+ p.insert(l, 2);
+ assertEquals(2, p.getWidgetCount());
+ assertEquals(0, p.getWidgetIndex(tb));
+ assertEquals(1, p.getWidgetIndex(l));
+ }
+}