/* * Copyright (C) 2012 Red Hat, Inc. and/or its affiliates. * * 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 org.jboss.errai.ui.shared.api.annotations; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.jboss.errai.common.client.api.annotations.BrowserEvent; import org.jboss.errai.common.client.dom.FocusEvent; import com.google.gwt.event.dom.client.DomEvent; import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import jsinterop.annotations.JsType; /** * This annotation may only be used in classes that has been annotated with {@link Templated}, or in a super-class of * said types. * <p> * Declares a method in a {@link Templated} component as a handler for standard {@link Event GWT Widget events}, * {@link DomEvent GWT native events}, and {@link BrowserEvent JS interop wrapped DOM events} fired by {@link DataField} * components and <code>data-field</code> elements within the component HTML template. Method handlers must accept a single * argument of the type of event to be handled. * <p> * The following scenarios are supported by this annotation: * <ol> * * <li>{@link BrowserEvent JS interop wrapped events} on any template element or {@link Templated} field * <li>GWT events on Widgets (Deprecated)</li> * <li>GWT events on {@link Element Elements} (Deprecated)</li> * <li>GWT events on native {@link JsType JsTypes} wrapping DOM elements (Deprecated)</li> * <li>Native DOM events on DOM elements (Deprecated)</li> * <li>Native DOM events on native {@link JsType JsTypes} wrapping DOM elements (Deprecated)</li> * * </ol> * <p> * <b>WARNING:</b> Native GWT events cannot be used in conjunction with GWT standard events, since upon addition to the * widget tree, GWT will override any {@link Widget#sinkEvents(int)} that may have been configured by Errai UI. * * <p> * <b>JS Interop wrapped events</b> * <p> * With this approach, the parameter of the {@link EventHandler} method is a type * annotated with {@link BrowserEvent} such as * {@link org.jboss.errai.common.client.dom.Event Errai's DOM event wrapper} * or any of its subtypes. The target element for the registered listener can be any * {@code @DataField} in a {@link Templated} bean or any {@code data-field} in the template HTML file. * <p> * For types like {@link org.jboss.errai.common.client.dom.Event Event} that do not specify allowable * event types via {@link BrowserEvent}, an {@link EventHandler} must use {@link ForEvent} to specify * the event types being listened to. When using {@link BrowserEvent} types that do specify event types * with {@link BrowserEvent}, {@link ForEvent} is optional. * <p> * Example: * <p> * * <pre> * {@code @Templated} * public class QuickHandlerComponent { * {@code @Inject} * {@code @DataField} * private Anchor link; * * // Listens to only "click" events on link. * {@code @EventHandler("link")} * public void doSomething({@code @ForEvent("click")} {@link org.jboss.errai.common.client.dom.Event Event} e) { * // do something * } * * // Listens to all events declared by {@link FocusEvent} in {@link BrowserEvent} ("blur", "focus", "focusin", and "focusout"). * {@code @EventHandler("link")} * public void doSomethingElse({@link FocusEvent} e) { * // do something else * } * } * </pre> * <p> * <b>GWT events on Widgets</b> * <p> * Example: * <p> * * <pre> * @Templated * public class WidgetHandlerComponent extends Composite { * @Inject * @DataField * private Button button; * * @EventHandler("button") * public void doSomethingC1(ClickEvent e) { * // do something * } * } * </pre> * <p> * <b>GWT events on DOM Elements</b> * <p> * Example: * <p> * * <pre> * @Templated * public class WidgetHandlerComponent extends Composite { * @Inject * @DataField * private DivElement button; * * @EventHandler("button") * public void doSomethingC1(ClickEvent e) { * // do something * } * } * </pre> * <p> * <b>GWT events on JsTypes</b> * <p> * Example: * <p> * * <pre> * @JsType(isNative = true) * public interface ButtonElementWrapper { * // ... * } * </pre> * * <pre> * @Templated * public class WidgetHandlerComponent extends Composite { * @Inject * @DataField * private ButtonElementWrapper button; * * @EventHandler("button") * public void doSomethingC1(ClickEvent e) { * // do something * } * } * </pre> * <p> * <b>Native events on DOM Elements</b> * <p> * This approach requires use of the {@link SinkNative} annotation, but does not require that target {@link Element} * instances be referenced via {@link DataField} in the {@link Templated} {@link Composite} component; they may also * target un-referenced <code>data-field</code> elements from the corresponding HTML template. * <p> * Example: * <p> * * <pre> * @Templated * public class QuickHandlerComponent extends Composite { * @DataField * private AnchorElement link = DOM.createAnchor().cast(); * * @EventHandler("link") * @SinkNative(Event.ONCLICK | Event.ONMOUSEOVER) * public void doSomething(Event e) { * // do something * } * * @EventHandler("div") * @SinkNative(Event.ONMOUSEOVER) * public void doSomethingElse(Event e) { * // do something with an element not otherwise referenced in our component * } * } * </pre> * <p> * <b>Native events on JsTypes</b> * <p> * This approach requires use of the {@link SinkNative} annotation, but does not require that target {@link Element} * instances be referenced via {@link DataField} in the {@link Templated} component; they may also target un-referenced * <code>data-field</code> elements from the corresponding HTML template. * <p> * Example: * <p> * * <pre> * @JsType(isNative = true) * public interface AnchorElementWrapper { * // ... * } * </pre> * * <pre> * @Templated * public class QuickHandlerComponent extends Composite { * @Inject * @DataField * private AnchorElementWrapper link; * * @EventHandler("link") * @SinkNative(Event.ONCLICK | Event.ONMOUSEOVER) * public void doSomething(Event e) { * // do something * } * * @EventHandler("div") * @SinkNative(Event.ONMOUSEOVER) * public void doSomethingElse(Event e) { * // do something with an element not otherwise referenced in our component * } * } * </pre> * * <p> * <b>See also:</b> {@link SinkNative}, {@link Templated}, {@link DataField} * * @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a> * @author Max Barkley <mbarkley@redhat.com> * */ @Inherited @Documented @Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface EventHandler { /** * Specifies the element for which the corresponding event type should be be handled. The handled event type is * defined by the handler method argument. By default, the event handler will be installed on the templated widget * itself. To handle events that occur on a child widget or DOM node in the template, specify a value. This value must * match either a {@link DataField} specified within the {@link Templated} {@link Composite} component (in the case of * handling GWT event types,) or a <code>data-field</code> attribute in the corresponding HTML template (in the case * of handling native DOM events.) */ String[] value() default "this"; }