Public (stephen.haberman@gmail.com):
Fixes GWT issue 5419, Panels do not emit AttachEvent
http://code.google.com/p/google-web-toolkit/issues/detail?id=5419
Review by: rjrjr@google.com
Review at http://gwt-code-reviews.appspot.com/998801
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9062 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/Composite.java b/user/src/com/google/gwt/user/client/ui/Composite.java
index 4f2c795..c90cc4e 100644
--- a/user/src/com/google/gwt/user/client/ui/Composite.java
+++ b/user/src/com/google/gwt/user/client/ui/Composite.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.user.client.ui;
+import com.google.gwt.event.logical.shared.AttachEvent;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
@@ -109,12 +110,14 @@
// Call onLoad() directly, because we're not calling super.onAttach().
onLoad();
+ AttachEvent.fire(this, true);
}
@Override
protected void onDetach() {
try {
onUnload();
+ AttachEvent.fire(this, false);
} finally {
// We don't want an exception in user code to keep us from calling the
// super implementation (or event listeners won't get cleaned up and
diff --git a/user/src/com/google/gwt/user/client/ui/Panel.java b/user/src/com/google/gwt/user/client/ui/Panel.java
index 6aa07c8..42515a7 100644
--- a/user/src/com/google/gwt/user/client/ui/Panel.java
+++ b/user/src/com/google/gwt/user/client/ui/Panel.java
@@ -176,26 +176,6 @@
}
/**
- * A Panel's onLoad method will be called after all of its children are
- * attached.
- *
- * @see Widget#onLoad()
- */
- @Override
- protected void onLoad() {
- }
-
- /**
- * A Panel's onUnload method will be called before its children become
- * detached themselves.
- *
- * @see Widget#onLoad()
- */
- @Override
- protected void onUnload() {
- }
-
- /**
* <p>
* This method must be called as part of the remove method of any Panel. It
* ensures that the Widget's parent is cleared. This method should be called
diff --git a/user/src/com/google/gwt/user/client/ui/Widget.java b/user/src/com/google/gwt/user/client/ui/Widget.java
index c80a25a..e0138a0 100644
--- a/user/src/com/google/gwt/user/client/ui/Widget.java
+++ b/user/src/com/google/gwt/user/client/ui/Widget.java
@@ -290,7 +290,7 @@
* <p>
* This method is called when a widget is attached to the browser's document.
* To receive notification after a Widget has been added to the document,
- * override the {@link #onLoad} method.
+ * override the {@link #onLoad} method or use {@link #addAttachHandler}.
* </p>
* <p>
* It is strongly recommended that you override {@link #onLoad()} or
@@ -328,13 +328,14 @@
// the attached flag is set. This allows widgets to be notified when they
// are fully attached, and panels when all of their children are attached.
onLoad();
+ AttachEvent.fire(this, true);
}
/**
* <p>
* This method is called when a widget is detached from the browser's
* document. To receive notification before a Widget is removed from the
- * document, override the {@link #onUnload} method.
+ * document, override the {@link #onUnload} method or use {@link #addAttachHandler}.
* </p>
* <p>
* It is strongly recommended that you override {@link #onUnload()} or
@@ -363,6 +364,7 @@
// onUnload() gets called *before* everything else (the opposite of
// onLoad()).
onUnload();
+ AttachEvent.fire(this, false);
} finally {
// Put this in a finally, just in case onUnload throws an exception.
try {
@@ -377,22 +379,16 @@
/**
* This method is called immediately after a widget becomes attached to the
- * browser's document. This default implementation notifies the widgets
- * {@link com.google.gwt.event.logical.shared.AttachEvent.Handler
- * AttachEvent.Handler}s.
+ * browser's document.
*/
protected void onLoad() {
- AttachEvent.fire(this, true);
}
/**
* This method is called immediately before a widget will be detached from the
- * browser's document. This default implementation notifies the widget's
- * {@link com.google.gwt.event.logical.shared.AttachEvent.Handler
- * AttachEvent.Handler}s.
+ * browser's document.
*/
protected void onUnload() {
- AttachEvent.fire(this, false);
}
/**
diff --git a/user/test/com/google/gwt/user/client/ui/CompositeTest.java b/user/test/com/google/gwt/user/client/ui/CompositeTest.java
index 37abcf8..902c56c 100644
--- a/user/test/com/google/gwt/user/client/ui/CompositeTest.java
+++ b/user/test/com/google/gwt/user/client/ui/CompositeTest.java
@@ -19,6 +19,7 @@
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
+import com.google.gwt.event.logical.shared.AttachEvent;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
@@ -30,6 +31,8 @@
*/
public class CompositeTest extends GWTTestCase {
+ static int orderIndex;
+
@Override
public String getModuleName() {
return "com.google.gwt.user.User";
@@ -132,4 +135,43 @@
*/
public void testNothing() {
}
+
+ public void testAttachAndDetachOrder() {
+ class TestAttachHandler implements AttachEvent.Handler {
+ int delegateAttachOrder;
+ int delegateDetachOrder;
+
+ public void onAttachOrDetach(AttachEvent event) {
+ if (event.isAttached()) {
+ delegateAttachOrder = ++orderIndex;
+ } else {
+ delegateDetachOrder = ++orderIndex;
+ }
+ }
+ }
+
+ class TestComposite extends Composite {
+ TextBox tb = new TextBox();
+
+ public TestComposite() {
+ initWidget(tb);
+ }
+ }
+
+ TestComposite c = new TestComposite();
+ TestAttachHandler ca = new TestAttachHandler();
+ TestAttachHandler wa = new TestAttachHandler();
+
+ c.addAttachHandler(ca);
+ c.tb.addAttachHandler(wa);
+
+ RootPanel.get().add(c);
+ RootPanel.get().remove(c);
+
+ assertTrue(ca.delegateAttachOrder > 0);
+ assertTrue(ca.delegateDetachOrder > 0);
+ assertTrue(ca.delegateAttachOrder > wa.delegateAttachOrder);
+ assertTrue(ca.delegateDetachOrder < wa.delegateDetachOrder);
+ }
+
}
diff --git a/user/test/com/google/gwt/user/client/ui/WidgetOnLoadTest.java b/user/test/com/google/gwt/user/client/ui/WidgetOnLoadTest.java
index 51293de..dc6170f 100644
--- a/user/test/com/google/gwt/user/client/ui/WidgetOnLoadTest.java
+++ b/user/test/com/google/gwt/user/client/ui/WidgetOnLoadTest.java
@@ -108,50 +108,68 @@
public void testOnLoadAndUnloadOrder() {
class TestAttachHandler implements AttachEvent.Handler {
- int delegateAttachOrder;
- int delegateDetachOrder;
+ int handleAttachOrder;
+ int handleDetachOrder;
public void onAttachOrDetach(AttachEvent event) {
if (event.isAttached()) {
- delegateAttachOrder = ++orderIndex;
+ handleAttachOrder = ++orderIndex;
} else {
- delegateDetachOrder = ++orderIndex;
+ handleDetachOrder = ++orderIndex;
}
}
}
TestPanel tp = new TestPanel();
+ TestAttachHandler tpa = new TestAttachHandler();
+ tp.addAttachHandler(tpa);
+
TestWidget tw = new TestWidget();
- TestAttachHandler ta = new TestAttachHandler();
- tw.addAttachHandler(ta);
+ TestAttachHandler twa = new TestAttachHandler();
+ tw.addAttachHandler(twa);
tp.add(tw);
RootPanel.get().add(tp);
RootPanel.get().remove(tp);
- // Trivial tests. Ensure that each panel/widget's onAttach/onDetach are
- // called before their associated onLoad/onUnload.
+ /*
+ * Ensure that each panel/widget's onAttach/onDetach are called before their
+ * associated onLoad/onUnload, and before attach events are fired
+ */
assertTrue(tp.onAttachOrder < tp.onLoadOrder);
assertTrue(tp.onDetachOrder < tp.onUnloadOrder);
assertTrue(tw.onAttachOrder < tw.onLoadOrder);
- assertTrue(tw.onLoadOrder < ta.delegateAttachOrder);
+ assertTrue(tw.onLoadOrder < twa.handleAttachOrder);
+ assertTrue(tp.onLoadOrder < tpa.handleAttachOrder);
assertTrue(tw.onDetachOrder < tw.onUnloadOrder);
- assertTrue(tw.onUnloadOrder < ta.delegateDetachOrder);
+ assertTrue(tw.onUnloadOrder < twa.handleDetachOrder);
+ assertTrue(tp.onUnloadOrder < tpa.handleDetachOrder);
- // Also trivial. Ensure that the panel's onAttach/onDetach is called before
- // its child's onAttach/onDetach.
+ /*
+ * Ensure that the panel's onAttach/onDetach is called before its child's
+ * onAttach/onDetach.
+ */
assertTrue(tp.onAttachOrder < tw.onAttachOrder);
+ assertTrue(tp.onDetachOrder < tw.onDetachOrder);
- // Ensure that the panel's onLoad is only called after its widgets are
- // attached/loaded.
+ /*
+ * Ensure that the panel's onLoad is only called after its widgets are
+ * attached/loaded, and likewise for the attach event listeners
+ */
assertTrue(tp.onLoadOrder > tw.onLoadOrder);
+ assertTrue(tpa.handleAttachOrder > twa.handleAttachOrder);
- // Ensure that the panel's onUnload is called before its widgets are
- // detached/unloaded.
+ /*
+ * Ensure that the panel's onUnload is called before its widgets are
+ * detached/unloaded.
+ */
assertTrue(tp.onUnloadOrder < tw.onUnloadOrder);
+ assertTrue(tpa.handleDetachOrder < twa.handleDetachOrder);
- // Make sure each widget/panel's elements are actually still attached to the
- // DOM during onLoad/onUnload.
+ /*
+ * Make sure each widget/panel's elements are actually still attached to the
+ * DOM during onLoad/onUnload.
+ */
assertTrue(tp.domAttachedOnLoad);
assertTrue(tp.domAttachedOnUnload);
assertTrue(tw.domAttachedOnLoad);