Allowing final methods as Tree.addOpenHandler to be bind with
@UiHandler and also customized generic events.
Review at http://gwt-code-reviews.appspot.com/881802
Review by: rjrjr@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8891 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/uibinder/rebind/HandlerEvaluator.java b/user/src/com/google/gwt/uibinder/rebind/HandlerEvaluator.java
index f9db520..311f18b 100644
--- a/user/src/com/google/gwt/uibinder/rebind/HandlerEvaluator.java
+++ b/user/src/com/google/gwt/uibinder/rebind/HandlerEvaluator.java
@@ -249,15 +249,21 @@
private JMethod getAddHandlerMethodForObject(JClassType objectType,
JClassType handlerType) throws UnableToCompleteException {
JMethod handlerMethod = null;
- for (JMethod method : objectType.getOverridableMethods()) {
+ JMethod alternativeHandlerMethod = null;
+ for (JMethod method : objectType.getInheritableMethods()) {
// Condition 1: returns HandlerRegistration?
if (method.getReturnType() == handlerRegistrationJClass) {
// Condition 2: single parameter of the same type of handlerType?
JParameter[] parameters = method.getParameters();
- if ((parameters.length == 1)
- && handlerType.equals(parameters[0].getType())) {
+ if (parameters.length != 1) {
+ continue;
+ }
+
+ JType subjectHandler = parameters[0].getType();
+
+ if (handlerType.equals(subjectHandler)) {
// Condition 3: does more than one method match the condition?
if (handlerMethod != null) {
@@ -268,9 +274,29 @@
handlerMethod = method;
}
+
+ /**
+ * Normalize the parameter and check for an alternative handler method.
+ * Might be the case where the given objectType is generic. In this
+ * situation we need to normalize the method parameter to test for
+ * equality. For instance:
+ *
+ * handlerType => TableHandler<String>
+ * subjectHandler => TableHandler
+ *
+ * This is done as an alternative handler method to preserve the
+ * original logic.
+ */
+ JParameterizedType ptype = handlerType.isParameterized();
+ if (ptype != null) {
+ if (subjectHandler.equals(ptype.getRawType())) {
+ alternativeHandlerMethod = method;
+ }
+ }
}
}
- return handlerMethod;
+
+ return (handlerMethod != null) ? handlerMethod : alternativeHandlerMethod;
}
/**
diff --git a/user/test/com/google/gwt/uibinder/test/client/CustomEvent.java b/user/test/com/google/gwt/uibinder/test/client/CustomEvent.java
new file mode 100644
index 0000000..901af5c
--- /dev/null
+++ b/user/test/com/google/gwt/uibinder/test/client/CustomEvent.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010 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.uibinder.test.client;
+
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.GwtEvent;
+
+/**
+ * A custom event test class.
+ *
+ * @param <T> the type associated with the event
+ */
+public class CustomEvent<T> extends GwtEvent<CustomEvent.Handler<T>> {
+
+ /**
+ * The handler for the custom event.
+ */
+ public interface Handler<T> extends EventHandler {
+ void onEvent(CustomEvent<T> event);
+ }
+
+ public static Type<Handler<?>> type;
+
+ static {
+ type = new Type<Handler<?>>();
+ }
+
+ private T value;
+
+ public CustomEvent(T value) {
+ this.value = value;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Type<Handler<T>> getAssociatedType() {
+ return (Type) type;
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ @Override
+ protected void dispatch(Handler<T> handler) {
+ handler.onEvent(this);
+ }
+}
diff --git a/user/test/com/google/gwt/uibinder/test/client/CustomEventWidget.java b/user/test/com/google/gwt/uibinder/test/client/CustomEventWidget.java
new file mode 100644
index 0000000..42b4e33
--- /dev/null
+++ b/user/test/com/google/gwt/uibinder/test/client/CustomEventWidget.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010 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.uibinder.test.client;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.ui.HTML;
+
+/**
+ * Tests a customized event by allowing registering of
+ * {@link CustomEvent.Handler}.
+ *
+ * @param <T> the type associated with the widget
+ */
+public class CustomEventWidget<T> extends HTML {
+
+ private final T value;
+
+ public CustomEventWidget(final T value) {
+ this.value = value;
+ addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ fireEvent(new CustomEvent<T>(value));
+ }
+ });
+ }
+
+ public HandlerRegistration addCustomHandler(CustomEvent.Handler<T> handler) {
+ return addHandler(handler, CustomEvent.type);
+ }
+}
diff --git a/user/test/com/google/gwt/uibinder/test/client/HandlerDemo.java b/user/test/com/google/gwt/uibinder/test/client/HandlerDemo.java
index 30ccdcd..ad812af 100644
--- a/user/test/com/google/gwt/uibinder/test/client/HandlerDemo.java
+++ b/user/test/com/google/gwt/uibinder/test/client/HandlerDemo.java
@@ -19,6 +19,8 @@
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOverEvent;
+import com.google.gwt.event.logical.shared.CloseEvent;
+import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.uibinder.client.UiBinder;
@@ -28,9 +30,10 @@
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FormPanel;
-import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.TextBox;
+import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;
+import com.google.gwt.user.client.ui.Widget;
/**
* A simple demo showing how UiHandler works.
@@ -38,14 +41,16 @@
public class HandlerDemo extends Composite {
@UiTemplate("HandlerDemo.ui.xml")
- interface MyUiBinder extends UiBinder<Panel, HandlerDemo> {
+ interface MyUiBinder extends UiBinder<Widget, HandlerDemo> {
}
private static final MyUiBinder binder = GWT.create(MyUiBinder.class);
@UiField FormPanel panelForm;
@UiField TextBox textBoxValueChange;
+ @UiField(provided = true) final CustomEventWidget<String> customEventWidget;
public HandlerDemo() {
+ this.customEventWidget = new CustomEventWidget<String>("a simple test");
initWidget(binder.createAndBindUi(this));
}
@@ -66,7 +71,7 @@
}
@UiHandler("buttonSubmit")
- @SuppressWarnings("unused")
+ @SuppressWarnings("unused")
void doClickSubmit(ClickEvent ignored) {
panelForm.submit();
}
@@ -81,7 +86,27 @@
eventMessage(event);
}
+ @UiHandler("tree")
+ void onTreeClose(CloseEvent<TreeItem> event) {
+ eventMessage(event);
+ }
+
+ @UiHandler("tree")
+ void onTreeOpen(OpenEvent<TreeItem> event) {
+ eventMessage(event);
+ }
+
+ @UiHandler("customEventWidget")
+ void onCustomEvent(CustomEvent<String> event) {
+ eventMessage("CustomEventWidget clicked. Event throwing '"
+ + event.getValue() + "'");
+ }
+
private void eventMessage(GwtEvent<?> event) {
- Window.alert(event.toDebugString());
+ eventMessage(event.toDebugString());
+ }
+
+ private void eventMessage(String message) {
+ Window.alert(message);
}
}