Fixes issue #616; refactores ComplexPanel to just implement IndexedPanel. So all ComplexPanel subclass now implement it as well. This is nice because it allows a lot of shared code to be merged into ComplexPanel.java
Suggested by: fredsa
Review by: jgw, knorton
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1050 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/ComplexPanel.java b/user/src/com/google/gwt/user/client/ui/ComplexPanel.java
index e6cdc6c..4ac2ab9 100644
--- a/user/src/com/google/gwt/user/client/ui/ComplexPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/ComplexPanel.java
@@ -22,24 +22,40 @@
/**
* Abstract base class for panels that can contain multiple child widgets.
*/
-public abstract class ComplexPanel extends Panel {
+public abstract class ComplexPanel extends Panel implements IndexedPanel {
private WidgetCollection children = new WidgetCollection(this);
+ 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 Iterator iterator() {
- return children.iterator();
+ return getChildren().iterator();
+ }
+
+ public boolean remove(int index) {
+ return remove(getWidget(index));
}
public boolean remove(Widget w) {
// Make sure this panel actually contains the child widget.
- if (!children.contains(w)) {
+ if (!getChildren().contains(w)) {
return false;
}
// Disown it.
disown(w);
- children.remove(w);
+ getChildren().remove(w);
return true;
}
@@ -48,9 +64,10 @@
*
* @param w the child widget to be added
* @param container the element within which the child will be contained
+ * @return the index at which the widget was added
*/
- protected void add(Widget w, Element container) {
- insert(w, container, children.size());
+ protected int add(Widget w, Element container) {
+ return insert(w, container, getChildren().size());
}
/**
@@ -68,13 +85,27 @@
* @param w the child widget to be added
* @param container the element within which the child will be contained
* @param beforeIndex the index before which the widget will be added
+ * @return the index at which the widget was added
*/
- protected void insert(Widget w, Element container, int beforeIndex) {
- if (w.getParent() == this) {
- return;
+ protected int insert(Widget w, Element container, int beforeIndex) {
+ if ((beforeIndex < 0) || (beforeIndex > getWidgetCount())) {
+ throw new IndexOutOfBoundsException();
}
-
+ // Call this early to ensure that the table doesn't end up partially
+ // constructed when an exception is thrown from adopt().
+ 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--;
+ }
+ }
adopt(w, container);
- children.insert(w, beforeIndex);
+ getChildren().insert(w, beforeIndex);
+ return beforeIndex;
}
}
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 d9953a3..2380b09 100644
--- a/user/src/com/google/gwt/user/client/ui/DeckPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/DeckPanel.java
@@ -30,7 +30,7 @@
* will be cleared.
* </p>
*/
-public class DeckPanel extends ComplexPanel implements IndexedPanel {
+public class DeckPanel extends ComplexPanel {
private Widget visibleWidget;
@@ -59,18 +59,6 @@
return getWidgetIndex(visibleWidget);
}
- public Widget getWidget(int index) {
- return getChildren().get(index);
- }
-
- public int getWidgetCount() {
- return getChildren().size();
- }
-
- public int getWidgetIndex(Widget child) {
- return getChildren().indexOf(child);
- }
-
/**
* Inserts a widget before the specified index.
*
@@ -80,10 +68,6 @@
* range
*/
public void insert(Widget w, int beforeIndex) {
- if ((beforeIndex < 0) || (beforeIndex > getWidgetCount())) {
- throw new IndexOutOfBoundsException();
- }
-
super.insert(w, getElement(), beforeIndex);
Element child = w.getElement();
@@ -92,10 +76,6 @@
w.setVisible(false);
}
- public boolean remove(int index) {
- return remove(getWidget(index));
- }
-
public boolean remove(Widget w) {
if (!super.remove(w)) {
return false;
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 6a04531..28266ce 100644
--- a/user/src/com/google/gwt/user/client/ui/FlowPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/FlowPanel.java
@@ -25,7 +25,7 @@
* <img class='gallery' src='FlowPanel.png'/>
* </p>
*/
-public class FlowPanel extends ComplexPanel implements IndexedPanel {
+public class FlowPanel extends ComplexPanel {
/**
* Creates an empty flow panel.
@@ -43,19 +43,15 @@
super.add(w, getElement());
}
- 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 boolean remove(int index) {
- return remove(getWidget(index));
+ /**
+ * 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) {
+ super.insert(w, getElement(), beforeIndex);
}
}
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 f7f99ba..c3baf5d 100644
--- a/user/src/com/google/gwt/user/client/ui/HorizontalPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/HorizontalPanel.java
@@ -25,8 +25,7 @@
* <img class='gallery' src='HorizontalPanel.png'/>
* </p>
*/
-public class HorizontalPanel extends CellPanel implements IndexedPanel,
- HasAlignment {
+public class HorizontalPanel extends CellPanel implements HasAlignment {
private HorizontalAlignmentConstant horzAlign = ALIGN_LEFT;
private Element tableRow;
@@ -61,18 +60,6 @@
return vertAlign;
}
- public Widget getWidget(int index) {
- return getChildren().get(index);
- }
-
- public int getWidgetCount() {
- return getChildren().size();
- }
-
- public int getWidgetIndex(Widget child) {
- return getChildren().indexOf(child);
- }
-
/**
* Inserts a widget before the specified index. If the Widget is already
* attached to the HorizontalPanel, it will be moved to the specified index.
@@ -83,34 +70,14 @@
* range
*/
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().
- 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();
+ beforeIndex = super.insert(w, td, beforeIndex);
DOM.insertChild(tableRow, td, beforeIndex);
- super.insert(w, td, beforeIndex);
-
setCellHorizontalAlignment(w, horzAlign);
setCellVerticalAlignment(w, vertAlign);
}
- public boolean remove(int index) {
- return remove(getWidget(index));
- }
-
public boolean remove(Widget w) {
if (w.getParent() != this) {
return false;
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 c819a97..54d7e82 100644
--- a/user/src/com/google/gwt/user/client/ui/StackPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/StackPanel.java
@@ -36,7 +36,7 @@
* {@example com.google.gwt.examples.StackPanelExample}
* </p>
*/
-public class StackPanel extends ComplexPanel implements IndexedPanel {
+public class StackPanel extends ComplexPanel {
private Element body;
private int visibleStack = -1;
@@ -63,34 +63,7 @@
* @param w the widget to be added
*/
public void add(Widget w) {
- // Call this early to ensure that the table doesn't end up partially
- // constructed when an exception is thrown from adopt().
- w.removeFromParent();
-
- int index = getWidgetCount();
-
- Element tr = DOM.createTR();
- Element td = DOM.createTD();
- DOM.appendChild(body, tr);
- DOM.appendChild(tr, td);
- setStyleName(td, "gwt-StackPanelItem", true);
- DOM.setElementPropertyInt(td, "__index", index);
- DOM.setElementPropertyInt(td, "__owner", hashCode());
- DOM.setElementProperty(td, "height", "1px");
-
- tr = DOM.createTR();
- td = DOM.createTD();
- DOM.appendChild(body, tr);
- DOM.appendChild(tr, td);
- DOM.setElementProperty(td, "height", "100%");
- DOM.setElementProperty(td, "vAlign", "top");
-
- super.add(w, td);
-
- setStackVisible(index, false);
- if (visibleStack == -1) {
- showStack(0);
- }
+ insert(w, getWidgetCount());
}
/**
@@ -125,16 +98,53 @@
return visibleStack;
}
- public Widget getWidget(int index) {
- return getChildren().get(index);
- }
+ /**
+ * 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();
+ Element tdh = DOM.createTD();
+ DOM.appendChild(trh, tdh);
- public int getWidgetCount() {
- return getChildren().size();
- }
+ // body
+ Element trb = DOM.createTR();
+ Element tdb = DOM.createTD();
+ DOM.appendChild(trb, tdb);
- public int getWidgetIndex(Widget child) {
- return getChildren().indexOf(child);
+ beforeIndex = super.insert(w, tdb, beforeIndex);
+ // DOM indices are 2x logical indices; 2 dom elements per stack item
+ int effectiveIndex = beforeIndex * 2;
+ // this ordering puts the body below the header
+ DOM.insertChild(body, trb, effectiveIndex);
+ DOM.insertChild(body, trh, effectiveIndex);
+
+ // header styling
+ setStyleName(tdh, "gwt-StackPanelItem", true);
+ DOM.setElementPropertyInt(tdh, "__owner", hashCode());
+ DOM.setElementProperty(tdh, "height", "1px");
+
+ // body styling
+ DOM.setElementProperty(tdb, "height", "100%");
+ DOM.setElementProperty(tdb, "vAlign", "top");
+
+ // Update indices of all elements to the right.
+ updateIndicesFrom(beforeIndex);
+
+ // Correct visible stack for new location.
+ if (visibleStack == -1) {
+ showStack(0);
+ } else {
+ setStackVisible(beforeIndex, false);
+ if (visibleStack >= beforeIndex) {
+ ++visibleStack;
+ }
+ }
}
public void onBrowserEvent(Event event) {
@@ -223,6 +233,7 @@
}
private boolean remove(Widget child, int index) {
+ // TODO: is this check really necessary?
if (child.getParent() != this) {
return false;
}
@@ -241,15 +252,9 @@
tr = DOM.getChild(body, rowIndex);
DOM.removeChild(body, tr);
super.remove(child);
- int rows = getWidgetCount() * 2;
- // Update all the indexes.
- for (int i = rowIndex; i < rows; i = i + 2) {
- Element childTR = DOM.getChild(body, i);
- Element td = DOM.getFirstChild(childTR);
- DOM.setElementPropertyInt(td, "__index", index);
- ++index;
- }
+ // Update indices of all elements to the right.
+ updateIndicesFrom(rowIndex);
return true;
}
@@ -271,4 +276,12 @@
getWidget(index).setVisible(visible);
}
+ private void updateIndicesFrom(int beforeIndex) {
+ for (int i = beforeIndex, c = getWidgetCount(); i < c; ++i) {
+ Element childTR = DOM.getChild(body, i * 2);
+ Element childTD = DOM.getFirstChild(childTR);
+ DOM.setElementPropertyInt(childTD, "__index", i);
+ }
+ }
+
}
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 947ccf2..a92c520 100644
--- a/user/src/com/google/gwt/user/client/ui/VerticalPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/VerticalPanel.java
@@ -25,8 +25,7 @@
* <img class='gallery' src='VerticalPanel.png'/>
* </p>
*/
-public class VerticalPanel extends CellPanel implements IndexedPanel,
- HasAlignment {
+public class VerticalPanel extends CellPanel implements HasAlignment {
private HorizontalAlignmentConstant horzAlign = ALIGN_LEFT;
private VerticalAlignmentConstant vertAlign = ALIGN_TOP;
@@ -57,18 +56,6 @@
return vertAlign;
}
- public Widget getWidget(int index) {
- return getChildren().get(index);
- }
-
- public int getWidgetCount() {
- return getChildren().size();
- }
-
- public int getWidgetIndex(Widget child) {
- return getChildren().indexOf(child);
- }
-
/**
* Inserts a widget before the specified index. If the Widget is already
* attached to the VerticalPanel, it will be moved to the specified index.
@@ -79,37 +66,16 @@
* range
*/
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().
- 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();
-
- DOM.insertChild(getBody(), tr, beforeIndex);
+ beforeIndex = super.insert(w, td, beforeIndex);
DOM.appendChild(tr, td);
-
- super.insert(w, td, beforeIndex);
+ DOM.insertChild(getBody(), tr, beforeIndex);
setCellHorizontalAlignment(w, horzAlign);
setCellVerticalAlignment(w, vertAlign);
}
- public boolean remove(int index) {
- return remove(getWidget(index));
- }
-
public boolean remove(Widget w) {
if (w.getParent() != this) {
return false;