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);