lightweightdispatcher.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 346 行

JAVA
346
字号
/* * @(#)LightweightDispatcher.java	1.16 06/10/10 *  * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation.  *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt).  *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA  *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions.  */package java.awt;import java.awt.event.AWTEventListener;import java.awt.event.MouseEvent;import java.awt.event.FocusEvent;import java.awt.event.KeyEvent;import sun.awt.SunToolkit;/** * Class to manage the dispatching of events to the lightweight * components contained by a native container. In basis profile, * there is only one native container which is the Frame. A * LightweightDispatcher is associated with the Frame and forwards * mouse events to the lightweight components contained in it. * */class LightweightDispatcher implements java.io.Serializable {    /*     * JDK 1.1 serialVersionUID     */    private static final long serialVersionUID = 5184291520170872969L;    LightweightDispatcher(Window window) {        this.window = window;        mouseEventTarget = null;    }	    /**     * Dispatches an event to a lightweight sub-component if necessary, and     * returns whether or not the event was forwarded to a lightweight     * sub-component.     *     * @param e the event     */    boolean dispatchEvent(AWTEvent e) {        boolean ret = false;        if (e instanceof MouseEvent) {            MouseEvent me = (MouseEvent) e;            ret = processMouseEvent(me);        }         if (e instanceof MouseEvent) {            // find out what component the mouse moved in            MouseEvent me = (MouseEvent) e;            if (me.getID() == MouseEvent.MOUSE_MOVED) {                cursorOn = window.getCursorTarget(me.getX(), me.getY());                updateCursor(cursorOn);            }        }        return ret;    }	    Component getFocusOwner() {        return focus;    }	    /**     * This method attempts to distribute a mouse event to a lightweight     * component.  It tries to avoid doing any unnecessary probes down     * into the component tree to minimize the overhead of determining     * where to route the event, since mouse movement events tend to     * come in large and frequent amounts.     */    private boolean processMouseEvent(MouseEvent e) {        int id = e.getID();        Component targetOver;        Component lwOver;        targetOver = window.getMouseEventTarget(e.getX(), e.getY(), true);        trackMouseEnterExit(targetOver, e);        if (mouseEventTarget == null) {            if (id == MouseEvent.MOUSE_MOVED ||                id == MouseEvent.MOUSE_PRESSED) {                lwOver = (targetOver != window) ? targetOver : null;                mouseEventTarget = lwOver;            }        }        if (mouseEventTarget != null) {            // pbp specific, check if the mouseEventTarget belongs to a             // different AppContext from the original target            // If they're different, we cannot dispatch the event             // with the current EventQueue's dispatcher thread, and             // need to repost the event with the retargetted component's            // EventQueue.            boolean repost = !appContextEquals((Component)e.getSource(), mouseEventTarget);            // we are currently forwarding to some component, check            // to see if we should continue to forward.            switch (id) {            case MouseEvent.MOUSE_DRAGGED:                if (dragging) {                    retargetMouseEvent(mouseEventTarget, id, e, repost);                }                break;            case MouseEvent.MOUSE_PRESSED:                dragging = true;                retargetMouseEvent(mouseEventTarget, id, e, repost);                break;            case MouseEvent.MOUSE_RELEASED:                Component releasedTarget = mouseEventTarget;                dragging = false;                retargetMouseEvent(mouseEventTarget, id, e, repost);                lwOver = window.getMouseEventTarget(e.getX(), e.getY(), false);                mouseEventTarget = lwOver;                // fix 4155217 component was hidden or moved in user                // code MOUSE_RELEASED handling                isClickOrphaned = lwOver != releasedTarget;                break;            case MouseEvent.MOUSE_CLICKED:                if (!isClickOrphaned) {                    retargetMouseEvent(mouseEventTarget, id, e, repost);                }                isClickOrphaned = false;                break;            case MouseEvent.MOUSE_ENTERED:                break;            case MouseEvent.MOUSE_EXITED:                if (!dragging) {                    mouseEventTarget = null;                }                break;            case MouseEvent.MOUSE_MOVED:                lwOver = window.getMouseEventTarget(e.getX(), e.getY(), false);                mouseEventTarget = lwOver;                retargetMouseEvent(mouseEventTarget, id, e, repost);                break;            }            e.consume();        }        return e.isConsumed();    }	    /*     * Generates enter/exit events as mouse moves over lw components     * @param targetOver	Target mouse is over (including native container)     * @param e			Mouse event in native container     */    private void trackMouseEnterExit(Component targetOver, MouseEvent e) {        Component	targetEnter = null;        int		id = e.getID();        if (id != MouseEvent.MOUSE_EXITED &&            id != MouseEvent.MOUSE_DRAGGED &&            isMouseInNativeContainer == false) {            // any event but an exit or drag means we're in the native container            isMouseInNativeContainer = true;        } else if (id == MouseEvent.MOUSE_EXITED) {            isMouseInNativeContainer = false;        }        if (isMouseInNativeContainer) {            targetEnter = targetOver;        }        //System.out.println("targetEnter = " + targetEnter);        //System.out.println("targetLastEntered = " + targetLastEntered);		        if (targetLastEntered == targetEnter) {            return;        }        retargetMouseEvent(targetLastEntered, MouseEvent.MOUSE_EXITED, e,                            !appContextEquals((Component)e.getSource(), targetLastEntered));        if (id == MouseEvent.MOUSE_EXITED) {            // consume native exit event if we generate one            e.consume();        }        retargetMouseEvent(targetEnter, MouseEvent.MOUSE_ENTERED, e,                           !appContextEquals((Component)e.getSource(), targetEnter));        if (id == MouseEvent.MOUSE_ENTERED) {            // consume native enter event if we generate one            e.consume();        }        //System.out.println("targetLastEntered: " + targetLastEntered);        targetLastEntered = targetEnter;    }	    /**     * Sends a mouse event to the current mouse event recipient using     * the given event (sent to the windowed host) as a srcEvent.  If     * the mouse event target is still in the component tree, the     * coordinates of the event are translated to those of the target.     * If the target has been removed, we don't bother to send the     * message.    * void retargetMouseEvent(Component target, int id, MouseEvent e) {    *   retargetMouseEvent(target, id, e, false) {    * }     */    /*     * @param repost - true if the new target belongs to a different AppContext      *                 from the original target     */    void retargetMouseEvent(Component target, int id, MouseEvent e, boolean repost) {        if (target == null) {            return; // mouse is over another hw component        }        int x = e.getX(), y = e.getY();        Component component;        for (component = target;            component != null && component != window;            component = component.getParent()) {            x -= component.x;            y -= component.y;        }        if (component != null) {            MouseEvent retargeted = new MouseEvent(target,                    id,                    e.getWhen(),                    e.getModifiers(),                    x,                    y,                    e.getClickCount(),                    e.isPopupTrigger());            if (target == window) {                // avoid recursively calling LightweightDispatcher...                window.dispatchEventToSelf(retargeted);            } else {                //target.dispatchEvent(retargeted);                if (repost)  {                   /* can't dispatch event with this EventQueue's                     * dispatcher thread. Need to repost to the right EQ.                   **/                   SunToolkit.postEvent(target.appContext, retargeted);                } else {                   target.dispatchEvent(retargeted);                }            }        }    }	    /**     * Set the cursor for a lightweight component     * Enforce that null cursor means inheriting from parent     */    void updateCursor(Component comp) {        // if user wants to change the cursor, we do it even mouse is dragging        // so LightweightDispatcher's dragging state is not checked here        // get the current mouse location	Point currentLoc = GraphicsEnvironment.getLocalGraphicsEnvironment().getMouseLocation();        cursorOn = window.getCursorTarget(currentLoc.x, currentLoc.y);        if (comp != cursorOn) {            return;        }                 if (comp == null) {            comp = window;        }        Cursor cursor = comp.getCursor();        while (cursor == null && comp != window) {            comp = comp.getParent();            if (comp == null) {                cursor = window.getCursor();                break;            }            cursor = comp.getCursor();        }        if (cursor != lightCursor) {            lightCursor = cursor;            window.changeCursor(lightCursor);        }    }    // --- member variables -------------------------------	    /**     * The windowed container that might be hosting events for     * lightweight components.     */    private Window window;    /**     * The current lightweight component that has focus that is being     * hosted by this container.  If this is a null reference then     * there is currently no focus on a lightweight component being     * hosted by this container     */    private Component focus;    /**     * The current lightweight component being hosted by this windowed     * component that has mouse events being forwarded to it.  If this     * is null, there are currently no mouse events being forwarded to     * a lightweight component.     */    private transient Component mouseEventTarget;    /**     *  lightweight component the mouse cursor is on     */    private transient Component cursorOn;    /**     * The last component entered     */    private transient Component targetLastEntered;    /**     * Is the mouse over the native container     */    private transient boolean isMouseInNativeContainer = false;    /**     * Is the next click event orphaned because the component hid/moved     */    private transient boolean isClickOrphaned = false;    /**     * Indicates if the mouse pointer is currently being dragged...     * this is needed because we may receive exit events while dragging     * and need to keep the current mouse target in this case.     */    private boolean dragging;    /**     * The cursor that is currently displayed for the lightwieght     * components.  Remember this cursor, so we do not need to     * change cursor on every mouse event.     */    private Cursor lightCursor;    private boolean appContextEquals(Component origTarget, Component newTarget) {       if (origTarget == null || newTarget == null) {          return true;       }       return (origTarget.appContext.getThreadGroup() == newTarget.appContext.getThreadGroup());    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?