com.google.gwt.user.client.Event.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.user.client.Event.java

Source

/*
 * Copyright 2009 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;

import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.HasNativeEvent;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.event.shared.HandlerRegistration;

/**
 * <p>
 * An opaque handle to a native DOM Event. An <code>Event</code> cannot be
 * created directly. Instead, use the <code>Event</code> type when returning a
 * native DOM event from JSNI methods. An <code>Event</code> passed back into
 * JSNI becomes the original DOM event the <code>Event</code> was created from,
 * and can be accessed in JavaScript code as expected. This is typically done by
 * calling methods in the {@link com.google.gwt.user.client.DOM} class.
 * </p>
 */
public class Event extends NativeEvent {
    /**
     * Fired when an element loses keyboard focus.
     */
    public static final int ONBLUR = 0x01000;

    /**
     * Fired when the value of an input element changes.
     */
    public static final int ONCHANGE = 0x00400;

    /**
     * Fired when the user clicks on an element.
     */
    public static final int ONCLICK = 0x00001;

    /**
     * Fired when the user double-clicks on an element.
     */
    public static final int ONDBLCLICK = 0x00002;

    /**
     * Fired when an image encounters an error.
     */
    public static final int ONERROR = 0x10000;

    /**
     * Fired when an element receives keyboard focus.
     */
    public static final int ONFOCUS = 0x00800;

    /**
     * Fired when the user gesture changes.
     */
    public static final int ONGESTURECHANGE = 0x2000000;

    /**
     * Fired when the user gesture ends.
     */
    public static final int ONGESTUREEND = 0x4000000;

    /**
     * Fired when the user gesture starts.
     */
    public static final int ONGESTURESTART = 0x1000000;

    /**
     * Fired when the user depresses a key.
     */
    public static final int ONKEYDOWN = 0x00080;

    /**
     * Fired when the a character is generated from a keypress (either directly
     * or through auto-repeat).
     */
    public static final int ONKEYPRESS = 0x00100;

    /**
     * Fired when the user releases a key.
     */
    public static final int ONKEYUP = 0x00200;

    /**
     * Fired when an element (normally an IMG) finishes loading.
     */
    public static final int ONLOAD = 0x08000;

    /**
     * Fired when an element that has mouse capture loses it.
     */
    public static final int ONLOSECAPTURE = 0x02000;

    /**
     * Fired when the user depresses a mouse button over an element.
     */
    public static final int ONMOUSEDOWN = 0x00004;

    /**
     * Fired when the mouse is moved within an element's area.
     */
    public static final int ONMOUSEMOVE = 0x00040;

    /**
     * Fired when the mouse is moved out of an element's area.
     */
    public static final int ONMOUSEOUT = 0x00020;

    /**
     * Fired when the mouse is moved into an element's area.
     */
    public static final int ONMOUSEOVER = 0x00010;

    /**
     * Fired when the user releases a mouse button over an element.
     */
    public static final int ONMOUSEUP = 0x00008;

    /**
     * Fired when the user scrolls the mouse wheel over an element.
     */
    public static final int ONMOUSEWHEEL = 0x20000;

    /**
     * Fired when the user pastes text into an input element.
     */
    public static final int ONPASTE = 0x80000;

    /**
     * Fired when a scrollable element's scroll offset changes.
     */
    public static final int ONSCROLL = 0x04000;

    /**
     * Fired when the user cancels touching an element.
     */
    public static final int ONTOUCHCANCEL = 0x800000;

    /**
     * Fired when the user ends touching an element.
     */
    public static final int ONTOUCHEND = 0x400000;

    /**
     * Fired when the user moves while touching an element.
     */
    public static final int ONTOUCHMOVE = 0x200000;

    /**
     * Fired when the user starts touching an element.
     */
    public static final int ONTOUCHSTART = 0x100000;

    /**
     * Fired when the user requests an element's context menu (usually by
     * right-clicking).
     */
    public static final int ONCONTEXTMENU = 0x40000;

    /**
     * A bit-mask covering both focus events (focus and blur).
     */
    public static final int FOCUSEVENTS = ONFOCUS | ONBLUR;

    /**
     * A bit-mask covering all keyboard events (down, up, and press).
     */
    public static final int KEYEVENTS = ONKEYDOWN | ONKEYPRESS | ONKEYUP;

    /**
     * A bit-mask covering all mouse events (down, up, move, over, and out), but
     * not click, dblclick, or wheel events.
     */
    public static final int MOUSEEVENTS = ONMOUSEDOWN | ONMOUSEUP | ONMOUSEMOVE | ONMOUSEOVER | ONMOUSEOUT;

    /**
     * A bit-mask covering all touch events (start, move, end, cancel).
     */
    public static final int TOUCHEVENTS = ONTOUCHSTART | ONTOUCHMOVE | ONTOUCHEND | ONTOUCHCANCEL;

    /**
     * A bit-mask covering all gesture events (start, change, end).
     */
    public static final int GESTUREEVENTS = ONGESTURESTART | ONGESTURECHANGE | ONGESTUREEND;

    /**
     * Value returned by accessors when the actual integer value is undefined.
     * In Development Mode, most accessors assert that the requested attribute
     * is reliable across all supported browsers.
     *
     * @see Event
     */
    @Deprecated
    public static final int UNDEFINED = 0;

    /**
     * The list of {@link NativePreviewHandler}. We use a list instead of a
     * handler manager for efficiency and because we want to fire the handlers
     * in reverse order. When the last handler is removed, handlers is reset to
     * null.
     */
    static HandlerManager handlers;

    /**
     * Adds an event preview to the preview stack. As long as this preview
     * remains on the top of the stack, it will receive all events before they
     * are fired to their listeners. Note that the event preview will receive
     * <u>all </u> events, including those received due to bubbling, whereas
     * normal event handlers only receive explicitly sunk events.
     * 
     * @param preview
     *            the event preview to be added to the stack.
     * @deprecated replaced by
     *             {@link #addNativePreviewHandler(NativePreviewHandler)}
     */
    @Deprecated
    public static void addEventPreview(EventPreview preview) {
        DOM.addEventPreview(preview);
    }

    /**
     * <p>
     * Adds a {@link NativePreviewHandler} that will receive all events before
     * they are fired to their handlers. Note that the handler will receive
     * <u>all</u> native events, including those received due to bubbling,
     * whereas normal event handlers only receive explicitly sunk events.
     * </p>
     * 
     * <p>
     * Unlike other event handlers, {@link NativePreviewHandler} are fired in
     * the reverse order that they are added, such that the last
     * {@link NativePreviewEvent} that was added is the first to be fired.
     * </p>
     * 
     * <p>
     * Please note that nondeterministic behavior will result if more than one
     * GWT application registers preview handlers. See <a href=
     * 'http://code.google.com/p/google-web-toolkit/issues/detail?id=3892'>issue
     * 3892</a> for details.
     * </p>
     *
     * @param handler
     *            the {@link NativePreviewHandler}
     * @return {@link HandlerRegistration} used to remove this handler
     */
    public static HandlerRegistration addNativePreviewHandler(final NativePreviewHandler handler) {
        assert handler != null : "Cannot add a null handler";
        DOM.maybeInitializeEventSystem();
        // Initialize the type
        NativePreviewEvent.getType();
        if (handlers == null) {
            handlers = new HandlerManager(null, true);
            NativePreviewEvent.singleton = new NativePreviewEvent();
        }
        return handlers.addHandler(NativePreviewEvent.TYPE, handler);
    }

    /**
     * Converts the {@link NativeEvent} to Event. This is always safe.
     * 
     * @param event
     *            the event to downcast
     */
    public static Event as(NativeEvent event) {
        return (Event) event;
    }

    /**
     * Fire a {@link NativePreviewEvent} for the native event.
     * 
     * @param nativeEvent
     *            the native event
     * @return true to fire the event normally, false to cancel the event
     */
    public static boolean fireNativePreviewEvent(NativeEvent nativeEvent) {
        return NativePreviewEvent.fire(handlers, nativeEvent);
    }

    /**
     * Gets the current event that is being fired. The current event is only
     * available within the lifetime of the onBrowserEvent function. Once the
     * onBrowserEvent method returns, the current event is reset to null.
     * 
     * @return the current event
     */
    public static Event getCurrentEvent() {
        return DOM.eventGetCurrentEvent();
    }

    /**
     * Gets the {@link EventListener} that will receive events for the given
     * element. Only one such listener may exist for a single element.
     * 
     * @param elem
     *            the element whose listener is to be set
     * @return the element's event listener
     */
    public static EventListener getEventListener(Element elem) {
        return DOM.getEventListener(elem);
    }

    /**
     * Gets the current set of events sunk by a given element.
     * 
     * @param elem
     *            the element whose events are to be retrieved
     * @return a bitfield describing the events sunk on this element (its
     *         possible values are described in {@link Event})
     */
    public static int getEventsSunk(Element elem) {
        return DOM.getEventsSunk(elem);
    }

    /**
     * Gets the enumerated type of this event given a valid event type name.
     * 
     * @param typeName
     *            the typeName to be tested
     * @return the event's enumerated type, or -1 if not defined
     */
    public static int getTypeInt(String typeName) {
        return DOM.impl.eventGetTypeInt(typeName);
    }

    /**
     * Releases mouse capture on the given element. Calling this method has no
     * effect if the element does not currently have mouse capture.
     * 
     * @param elem
     *            the element to release capture
     * @see #setCapture(Element)
     */
    public static void releaseCapture(Element elem) {
        DOM.releaseCapture(elem);
    }

    /**
     * Removes an element from the preview stack. This element will no longer
     * capture events, though any preview underneath it will begin to do so.
     * 
     * @param preview
     *            the event preview to be removed from the stack
     * @deprecated use {@link HandlerRegistration} returned from
     *             {@link Event#addNativePreviewHandler(NativePreviewHandler)}
     */
    @Deprecated
    public static void removeEventPreview(EventPreview preview) {
        DOM.removeEventPreview(preview);
    }

    /**
     * Sets mouse-capture on the given element. This element will directly
     * receive all mouse events until {@link #releaseCapture(Element)} is called
     * on it.
     * 
     * @param elem
     *            the element on which to set mouse capture
     */
    public static void setCapture(Element elem) {
        DOM.setCapture(elem);
    }

    /**
     * Sets the {@link EventListener} to receive events for the given element.
     * Only one such listener may exist for a single element.
     * 
     * @param elem
     *            the element whose listener is to be set
     * @param listener
     *            the listener to receive {@link Event events}
     */
    public static void setEventListener(Element elem, EventListener listener) {
        DOM.setEventListener(elem, listener);
    }

    /**
     * Sets the current set of events sunk by a given element. These events will
     * be fired to the nearest {@link EventListener} specified on any of the
     * element's parents.
     * 
     * @param elem
     *            the element whose events are to be retrieved
     * @param eventBits
     *            a bitfield describing the events sunk on this element (its
     *            possible values are described in {@link Event})
     */
    public static void sinkEvents(Element elem, int eventBits) {
        DOM.sinkEvents(elem, eventBits);
    }

    /**
     * Not directly instantiable. Subclasses should also define a protected
     * no-arg constructor to prevent client code from directly instantiating the
     * class.
     */
    protected Event() {
    }

    /**
     * Cancels bubbling for the given event. This will stop the event from being
     * propagated to parent elements.
     * 
     * @param cancel
     *            <code>true</code> to cancel bubbling
     * @deprecated use {@link NativeEvent#stopPropagation()} instead
     */
    @Deprecated
    public final void cancelBubble(boolean cancel) {
        DOM.eventCancelBubble(this, cancel);
    }

    /**
     * Gets the current target element of this event. This is the element whose
     * listener fired last, not the element which fired the event initially.
     * 
     * @return the event's current target element
     * @deprecated use {@link NativeEvent#getCurrentEventTarget()} instead
     */
    @Deprecated
    public final Element getCurrentTarget() {
        return getCurrentEventTarget().cast();
    }

    /**
     * Gets the element from which the mouse pointer was moved (only valid for
     * {@link Event#ONMOUSEOVER}).
     * 
     * @deprecated use {@link NativeEvent#getRelatedEventTarget()} instead
     * @return the element from which the mouse pointer was moved
     */
    @Deprecated
    public final Element getFromElement() {
        return DOM.eventGetFromElement(this);
    }

    /**
     * Gets the related target for this event.
     * 
     * @return the related target
     * @deprecated use {@link NativeEvent#getRelatedEventTarget()} instead
     */
    @Deprecated
    public final Element getRelatedTarget() {
        return getRelatedEventTarget().cast();
    }

    /**
     * Gets the key-repeat state of this event.
     * 
     * @return <code>true</code> if this key event was an auto-repeat
     * @deprecated not supported on all browsers
     */
    @Deprecated
    public final boolean getRepeat() {
        return DOM.eventGetRepeat(this);
    }

    /**
     * Returns the element that was the actual target of the given event.
     * 
     * @return the target element
     * @deprecated use {@link NativeEvent#getEventTarget()} instead
     */
    @Deprecated
    public final Element getTarget() {
        return getEventTarget().cast();
    }

    /**
     * Gets the element to which the mouse pointer was moved (only valid for
     * {@link Event#ONMOUSEOUT}).
     * 
     * @deprecated use {@link NativeEvent#getRelatedEventTarget()} instead
     * @return the element to which the mouse pointer was moved
     */
    @Deprecated
    public final Element getToElement() {
        return DOM.eventGetToElement(this);
    }

    /**
     * Gets the enumerated type of this event, as defined by {@link #ONCLICK},
     * {@link #ONMOUSEDOWN}, and so forth.
     * 
     * @return the event's enumerated type
     */
    public final int getTypeInt() {
        return DOM.eventGetType(this);
    }

    /**
     * Represents a preview of a native {@link Event}.
     */
    public static class NativePreviewEvent extends GwtEvent<NativePreviewHandler> implements HasNativeEvent {
        /**
         * Handler type.
         */
        private static Type<NativePreviewHandler> TYPE;

        /**
         * The singleton instance of {@link NativePreviewEvent}.
         */
        private static NativePreviewEvent singleton;

        /**
         * Gets the type associated with this event.
         * 
         * @return returns the handler type
         */
        public static Type<NativePreviewHandler> getType() {
            if (TYPE == null) {
                TYPE = new Type<NativePreviewHandler>();
            }
            return TYPE;
        }

        /**
         * Fire a {@link NativePreviewEvent} for the native event.
         * 
         * @param handlers
         *            the {@link HandlerManager}
         * @param nativeEvent
         *            the native event
         * @return true to fire the event normally, false to cancel the event
         */
        private static boolean fire(HandlerManager handlers, NativeEvent nativeEvent) {
            if (TYPE != null && handlers != null && handlers.isEventHandled(TYPE)) {
                // Cache the current values in the singleton in case we are in
                // the
                // middle of handling another event.
                boolean lastIsCanceled = singleton.isCanceled;
                boolean lastIsConsumed = singleton.isConsumed;
                boolean lastIsFirstHandler = singleton.isFirstHandler;
                NativeEvent lastNativeEvent = singleton.nativeEvent;
                // Revive the event
                singleton.revive();
                singleton.setNativeEvent(nativeEvent);
                // Fire the event
                handlers.fireEvent(singleton);
                boolean ret = !(singleton.isCanceled() && !singleton.isConsumed());
                // Restore the state of the singleton.
                singleton.isCanceled = lastIsCanceled;
                singleton.isConsumed = lastIsConsumed;
                singleton.isFirstHandler = lastIsFirstHandler;
                singleton.nativeEvent = lastNativeEvent;
                return ret;
            }
            return true;
        }

        /**
         * A boolean indicating that the native event should be canceled.
         */
        private boolean isCanceled = false;

        /**
         * A boolean indicating whether or not canceling the native event should
         * be prevented. This supercedes {@link #isCanceled}.
         */
        private boolean isConsumed = false;

        /**
         * A boolean indicating that the current handler is at the top of the
         * event preview stack.
         */
        private boolean isFirstHandler = false;

        /**
         * The event being previewed.
         */
        private NativeEvent nativeEvent;

        /**
         * Cancel the native event and prevent it from firing. Note that the
         * event can still fire if another handler calls {@link #consume()}.
         * 
         * Classes overriding this method should still call super.cancel().
         */
        public void cancel() {
            String type = nativeEvent.getType();
            isCanceled = true;
        }

        /**
         * Consume the native event and prevent it from being canceled, even if
         * it has already been canceled by another handler.
         * {@link NativePreviewHandler} that fire first have priority over later
         * handlers, so all handlers should check if the event has already been
         * canceled before calling this method.
         */
        public void consume() {
            isConsumed = true;
        }

        @Override
        public final Type<NativePreviewHandler> getAssociatedType() {
            return TYPE;
        }

        public NativeEvent getNativeEvent() {
            return nativeEvent;
        }

        /**
         * Gets the type int corresponding to the native event that triggered
         * this preview.
         * 
         * @return the type int associated with this native event
         */
        public final int getTypeInt() {
            return Event.as(getNativeEvent()).getTypeInt();
        }

        /**
         * Has the event already been canceled? Note that {@link #isConsumed()}
         * will still return true if the native event has also been consumed.
         * 
         * @return true if the event has been canceled
         * @see #cancel()
         */
        public boolean isCanceled() {
            return isCanceled;
        }

        /**
         * Has the native event been consumed? Note that {@link #isCanceled()}
         * will still return true if the native event has also been canceled.
         * 
         * @return true if the event has been consumed
         * @see #consume()
         */
        public boolean isConsumed() {
            return isConsumed;
        }

        /**
         * Is the current handler the first to preview this event?
         * 
         * @return true if the current handler is the first to preview the event
         */
        public boolean isFirstHandler() {
            return isFirstHandler;
        }

        /**
         * Set the native event.
         * 
         * @param nativeEvent
         *            the native {@link Event} being previewed.
         */
        private void setNativeEvent(NativeEvent nativeEvent) {
            this.nativeEvent = nativeEvent;
        }

        @Override
        protected void dispatch(NativePreviewHandler handler) {
            handler.onPreviewNativeEvent(this);
            singleton.isFirstHandler = false;
        }

        @Override
        protected void revive() {
            super.revive();
            isCanceled = false;
            isConsumed = false;
            isFirstHandler = true;
            nativeEvent = null;
        }
    }

    /**
     * Handler interface for {@link NativePreviewEvent} events.
     */
    public static interface NativePreviewHandler extends EventHandler {
        /**
         * Called when {@link NativePreviewEvent} is fired.
         * 
         * @param event
         *            the {@link NativePreviewEvent} that was fired
         */
        void onPreviewNativeEvent(NativePreviewEvent event);
    }
}