Revision: 10290
Author: [email protected]
Date: Tue Jun 7 09:30:28 2011
Log: Extracts AbstractComposite<W> out of Composite, to allow type safe
calls to gwtWidget(). Deprecates ResizeComposite and replaces it with
RequiresResizeComposite, which moves the "must implement
RequireResize" requirement check to compile time.
Review at http://gwt-code-reviews.appspot.com/1453807
Review by: [email protected]
http://code.google.com/p/google-web-toolkit/source/detail?r=10290
Added:
/trunk/user/src/com/google/gwt/user/client/ui/AbstractComposite.java
/trunk/user/src/com/google/gwt/user/client/ui/RequiresResizeComposite.java
Modified:
/trunk/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/client/desktop/DesktopTaskListView.java
/trunk/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/client/desktop/MobileWebAppShellDesktop.java
/trunk/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/client/mobile/MobileWebAppShellMobile.java
/trunk/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/client/tablet/MobileWebAppShellTablet.java
/trunk/tools/api-checker/config/gwt23_24userApi.conf
/trunk/user/src/com/google/gwt/user/client/ui/Composite.java
/trunk/user/src/com/google/gwt/user/client/ui/ResizeComposite.java
/trunk/user/src/com/google/gwt/user/client/ui/StackLayoutPanel.java
/trunk/user/src/com/google/gwt/user/client/ui/TabLayoutPanel.java
=======================================
--- /dev/null
+++ /trunk/user/src/com/google/gwt/user/client/ui/AbstractComposite.java
Tue Jun 7 09:30:28 2011
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2011 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.event.logical.shared.AttachEvent;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+
+/**
+ * A type of widget that can wrap another widget, hiding the wrapped
widget's
+ * methods. When added to a panel, a composite behaves exactly as if the
widget
+ * it wraps had been added.
+ * <p>
+ * The composite is useful for creating a single widget out of an
aggregate of
+ * multiple other widgets contained in a single panel.
+ *
+ * @see Composite
+ *
+ * @param <W> the type of IsWidget this composite wraps
+ */
+public class AbstractComposite<W extends IsWidget> extends Widget {
+
+ private W isWidget;
+
+ @Override
+ public boolean isAttached() {
+ if (isWidget != null) {
+ return isWidget.asWidget().isAttached();
+ }
+ return false;
+ }
+
+ @Override
+ public void onBrowserEvent(Event event) {
+ // Fire any handler added to the composite itself.
+ super.onBrowserEvent(event);
+
+ // Delegate events to the widget.
+ getWidget().asWidget().onBrowserEvent(event);
+ }
+
+ /**
+ * Provides subclasses access to the widget that defines this composite.
+ *
+ * @return the widget
+ */
+ protected W getWidget() {
+ return isWidget;
+ }
+
+ /**
+ * Sets the widget to be wrapped by the composite. The wrapped widget
must be
+ * set before calling any {@link Widget} methods on this object, or
adding it
+ * to a panel. This method may only be called once for a given composite.
+ * <p>
+ * The widget returned by the wrapped object's {@link
IsWidget#asWidget()} method
+ * must be stable. If it changes, the results are unpredictable.
+ *
+ * @param isWidget the widget to be wrapped
+ */
+ protected void initWidget(W isWidget) {
+ // Validate. Make sure the widget is not being set twice.
+ if (this.isWidget != null) {
+ throw new IllegalStateException("initWidget() may only be called
once.");
+ }
+
+ // TODO rjrjr: avoids breaking some mocked unit tests, should fix the
tests instead
+ Widget newChild = isWidget instanceof Widget ? (Widget) isWidget :
isWidget.asWidget();
+
+ // Detach the new child.
+ newChild.removeFromParent();
+
+ // Use the contained widget's element as the composite's element,
+ // effectively merging them within the DOM.
+ setElement(newChild.getElement());
+
+ // Logical attach.
+ this.isWidget = isWidget;
+
+ // Adopt.
+ newChild.setParent(this);
+ }
+
+ /**
+ *
+ */
+ @Override
+ protected void onAttach() {
+ Widget asWidget = getWidget().asWidget();
+
+ if (!isOrWasAttached()) {
+ asWidget.sinkEvents(eventsToSink);
+ eventsToSink = -1;
+ }
+
+ asWidget.onAttach();
+
+ // Clobber the widget's call to setEventListener(), causing all events
to
+ // be routed to this composite, which will delegate back to the widget
by
+ // default (note: it's not necessary to clear this in onDetach(),
because
+ // the widget's onDetach will do so).
+ DOM.setEventListener(getElement(), this);
+
+ // 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
+ // the attached flag will be wrong).
+ getWidget().asWidget().onDetach();
+ }
+ }
+}
=======================================
--- /dev/null
+++
/trunk/user/src/com/google/gwt/user/client/ui/RequiresResizeComposite.java
Tue Jun 7 09:30:28 2011
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2011 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;
+
+/**
+ * A {@link AbstractComposite} implementation that implements {@link
RequiresResize}
+ * and automatically delegates that interface's methods to its wrapped
widget,
+ * which must itself implement {@link RequiresResize}.
+ *
+ * @param <W> the type of widget wrapped
+ */
+public abstract class RequiresResizeComposite<W extends Widget &
RequiresResize> extends
+ AbstractComposite<W> implements RequiresResize {
+
+ public void onResize() {
+ getWidget().onResize();
+ }
+}
=======================================
---
/trunk/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/client/desktop/DesktopTaskListView.java
Wed Jun 1 11:32:36 2011
+++
/trunk/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/client/desktop/DesktopTaskListView.java
Tue Jun 7 09:30:28 2011
@@ -22,7 +22,7 @@
import com.google.gwt.user.cellview.client.DataGrid;
import
com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.TextColumn;
-import com.google.gwt.user.client.ui.ResizeComposite;
+import com.google.gwt.user.client.ui.RequiresResizeComposite;
import com.google.gwt.view.client.NoSelectionModel;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionModel;
@@ -33,7 +33,7 @@
/**
* View used to display the list of Tasks.
*/
-public class DesktopTaskListView extends ResizeComposite implements
TaskListView {
+public class DesktopTaskListView extends
RequiresResizeComposite<DataGrid<?>> implements TaskListView {
/**
* Displays the list of tasks.
=======================================
---
/trunk/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/client/desktop/MobileWebAppShellDesktop.java
Wed Jun 1 07:45:02 2011
+++
/trunk/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/client/desktop/MobileWebAppShellDesktop.java
Tue Jun 7 09:30:28 2011
@@ -49,7 +49,7 @@
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
-import com.google.gwt.user.client.ui.ResizeComposite;
+import com.google.gwt.user.client.ui.RequiresResizeComposite;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.SelectionChangeEvent;
@@ -63,7 +63,7 @@
/**
* Desktop version of the UI shell.
*/
-public class MobileWebAppShellDesktop extends ResizeComposite implements
MobileWebAppShell {
+public class MobileWebAppShellDesktop extends
RequiresResizeComposite<DockLayoutPanel> implements MobileWebAppShell {
/**
* CSS override used for the main menu.
@@ -71,7 +71,7 @@
interface MainMenuStyle extends CellList.Style {
}
- interface MobileWebAppShellDesktopUiBinder extends UiBinder<Widget,
MobileWebAppShellDesktop> {
+ interface MobileWebAppShellDesktopUiBinder extends
UiBinder<DockLayoutPanel, MobileWebAppShellDesktop> {
}
/**
@@ -147,7 +147,6 @@
/**
* Construct a new {@link MobileWebAppShellDesktop}.
- * @param clientFactory the {@link ClientFactory} of shared resources
*/
public MobileWebAppShellDesktop(EventBus bus, final PlaceController
placeController,
TaskListView taskListView, TaskEditView taskEditView, TaskReadView
taskReadView) {
=======================================
---
/trunk/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/client/mobile/MobileWebAppShellMobile.java
Wed Jun 1 07:45:02 2011
+++
/trunk/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/client/mobile/MobileWebAppShellMobile.java
Tue Jun 7 09:30:28 2011
@@ -36,15 +36,15 @@
import com.google.gwt.user.client.ui.DeckLayoutPanel;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.LayoutPanel;
-import com.google.gwt.user.client.ui.ResizeComposite;
+import com.google.gwt.user.client.ui.RequiresResizeComposite;
import com.google.gwt.user.client.ui.Widget;
/**
* Mobile version of the UI shell.
*/
-public class MobileWebAppShellMobile extends ResizeComposite implements
MobileWebAppShell {
-
- interface MobileWebAppShellMobileUiBinder extends UiBinder<Widget,
MobileWebAppShellMobile> {
+public class MobileWebAppShellMobile extends
RequiresResizeComposite<LayoutPanel> implements MobileWebAppShell {
+
+ interface MobileWebAppShellMobileUiBinder extends UiBinder<LayoutPanel,
MobileWebAppShellMobile> {
}
private static MobileWebAppShellMobileUiBinder uiBinder =
=======================================
---
/trunk/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/client/tablet/MobileWebAppShellTablet.java
Wed Jun 1 07:45:02 2011
+++
/trunk/samples/mobilewebapp/src/main/java/com/google/gwt/sample/mobilewebapp/client/tablet/MobileWebAppShellTablet.java
Tue Jun 7 09:30:28 2011
@@ -34,7 +34,7 @@
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.ResizeComposite;
+import com.google.gwt.user.client.ui.RequiresResizeComposite;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
@@ -43,9 +43,9 @@
*
* TODO(rjrjr): this thing needs a presenter. Not an activity. A presenter.
*/
-public class MobileWebAppShellTablet extends ResizeComposite implements
MobileWebAppShell {
-
- interface MobileWebAppShellTabletUiBinder extends UiBinder<Widget,
MobileWebAppShellTablet> {
+public class MobileWebAppShellTablet extends
RequiresResizeComposite<DockLayoutPanel> implements MobileWebAppShell {
+
+ interface MobileWebAppShellTabletUiBinder extends
UiBinder<DockLayoutPanel, MobileWebAppShellTablet> {
}
private static MobileWebAppShellTabletUiBinder uiBinder =
=======================================
--- /trunk/tools/api-checker/config/gwt23_24userApi.conf Mon Jun 6
10:00:08 2011
+++ /trunk/tools/api-checker/config/gwt23_24userApi.conf Tue Jun 7
09:30:28 2011
@@ -157,3 +157,11 @@
com.google.gwt.user.client.ui.Image::prefetch(Ljava/lang/String;)
OVERLOADED_METHOD_CALL
com.google.gwt.user.client.ui.Image::setUrl(Ljava/lang/String;)
OVERLOADED_METHOD_CALL
com.google.gwt.user.client.ui.Image::setUrlAndVisibleRect(Ljava/lang/String;IIII)
OVERLOADED_METHOD_CALL
+
+# Change StackLayoutPanel and TabLayoutPanel to get new superclass
+com.google.gwt.user.client.ui.StackLayoutPanel::getWidget()
OVERRIDABLE_METHOD_RETURN_TYPE_CHANGE from class
com.google.gwt.user.client.ui.Widget to class
com.google.gwt.user.client.ui.LayoutPanel
+com.google.gwt.user.client.ui.StackLayoutPanel::initWidget(Lcom/google/gwt/user/client/ui/Widget;)
MISSING
+com.google.gwt.user.client.ui.StackLayoutPanel::setWidget(Lcom/google/gwt/user/client/ui/Widget;)
MISSING
+com.google.gwt.user.client.ui.TabLayoutPanel::getWidget()
OVERRIDABLE_METHOD_RETURN_TYPE_CHANGE from class
com.google.gwt.user.client.ui.Widget to class
com.google.gwt.user.client.ui.LayoutPanel
+com.google.gwt.user.client.ui.TabLayoutPanel::initWidget(Lcom/google/gwt/user/client/ui/Widget;)
MISSING
+com.google.gwt.user.client.ui.TabLayoutPanel::setWidget(Lcom/google/gwt/user/client/ui/Widget;)
MISSING
=======================================
--- /trunk/user/src/com/google/gwt/user/client/ui/Composite.java Thu Oct 14
06:34:39 2010
+++ /trunk/user/src/com/google/gwt/user/client/ui/Composite.java Tue Jun 7
09:30:28 2011
@@ -15,115 +15,25 @@
*/
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;
-
/**
- * A type of widget that can wrap another widget, hiding the wrapped
widget's
- * methods. When added to a panel, a composite behaves exactly as if the
widget
- * it wraps had been added.
- *
- * <p>
- * The composite is useful for creating a single widget out of an
aggregate of
- * multiple other widgets contained in a single panel.
- * </p>
- *
- * <p>
+ * Simple extension of {@link AbstractComposite} that doesn't require type
+ * parameters. This originally was the only implementation of Composite,
before
+ * {@link AbstractComposite} was introduced to allow strong typing and
deferred
+ * construction.
+ *
* <h3>Example</h3>
* {@example com.google.gwt.examples.CompositeExample}
* </p>
*/
-public abstract class Composite extends Widget {
-
- private Widget widget;
-
- @Override
- public boolean isAttached() {
- if (widget != null) {
- return widget.isAttached();
- }
- return false;
- }
-
- @Override
- public void onBrowserEvent(Event event) {
- // Fire any handler added to the composite itself.
- super.onBrowserEvent(event);
-
- // Delegate events to the widget.
- widget.onBrowserEvent(event);
- }
-
+public abstract class Composite extends AbstractComposite<Widget> {
+
/**
- * Provides subclasses access to the topmost widget that defines this
- * composite.
- *
- * @return the widget
+ * Provided for compatibility with legacy unit tests that mocked
+ * this specific method.
*/
- protected Widget getWidget() {
- return widget;
- }
-
- /**
- * Sets the widget to be wrapped by the composite. The wrapped widget
must be
- * set before calling any {@link Widget} methods on this object, or
adding it
- * to a panel. This method may only be called once for a given composite.
- *
- * @param widget the widget to be wrapped
- */
- protected void initWidget(Widget widget) {
- // Validate. Make sure the widget is not being set twice.
- if (this.widget != null) {
- throw new IllegalStateException("Composite.initWidget() may only be "
- + "called once.");
- }
-
- // Detach the new child.
- widget.removeFromParent();
-
- // Use the contained widget's element as the composite's element,
- // effectively merging them within the DOM.
- setElement(widget.getElement());
-
- // Logical attach.
- this.widget = widget;
-
- // Adopt.
- widget.setParent(this);
- }
-
- @Override
- protected void onAttach() {
- if (!isOrWasAttached()) {
- widget.sinkEvents(eventsToSink);
- eventsToSink = -1;
- }
-
- widget.onAttach();
-
- // Clobber the widget's call to setEventListener(), causing all events
to
- // be routed to this composite, which will delegate back to the widget
by
- // default (note: it's not necessary to clear this in onDetach(),
because
- // the widget's onDetach will do so).
- DOM.setEventListener(getElement(), this);
-
- // 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
- // the attached flag will be wrong).
- widget.onDetach();
- }
+ @Deprecated
+ protected void initWidget(Widget widget) {
+ super.initWidget(widget);
}
/**
=======================================
--- /trunk/user/src/com/google/gwt/user/client/ui/ResizeComposite.java Mon
Sep 13 05:11:29 2010
+++ /trunk/user/src/com/google/gwt/user/client/ui/ResizeComposite.java Tue
Jun 7 09:30:28 2011
@@ -19,7 +19,9 @@
* A {@link Composite} implementation that implements {@link
RequiresResize} and
* automatically delegates that interface's methods to its wrapped widget,
which
* must itself implement {@link RequiresResize}.
+ * @deprecated Use {@link RequiresResizeComposite}
*/
+@Deprecated
public abstract class ResizeComposite extends Composite implements
RequiresResize {
=======================================
--- /trunk/user/src/com/google/gwt/user/client/ui/StackLayoutPanel.java Thu
Feb 17 05:39:09 2011
+++ /trunk/user/src/com/google/gwt/user/client/ui/StackLayoutPanel.java Tue
Jun 7 09:30:28 2011
@@ -95,7 +95,7 @@
* </g:StackLayoutPanel>
* </pre>
*/
-public class StackLayoutPanel extends ResizeComposite implements
HasWidgets,
+public class StackLayoutPanel extends RequiresResizeComposite<LayoutPanel>
implements HasWidgets,
ProvidesResize, IndexedPanel.ForIsWidget, AnimatedLayout,
HasBeforeSelectionHandlers<Integer>, HasSelectionHandlers<Integer> {
=======================================
--- /trunk/user/src/com/google/gwt/user/client/ui/TabLayoutPanel.java Thu
Mar 3 09:02:50 2011
+++ /trunk/user/src/com/google/gwt/user/client/ui/TabLayoutPanel.java Tue
Jun 7 09:30:28 2011
@@ -94,7 +94,7 @@
* </g:TabLayoutPanel>
* </pre>
*/
-public class TabLayoutPanel extends ResizeComposite implements HasWidgets,
+public class TabLayoutPanel extends RequiresResizeComposite<LayoutPanel>
implements HasWidgets,
ProvidesResize, IndexedPanel.ForIsWidget, AnimatedLayout,
HasBeforeSelectionHandlers<Integer>, HasSelectionHandlers<Integer> {
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors