aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/java/awt/LightweightDispatcher.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/java/awt/LightweightDispatcher.java')
-rw-r--r--libjava/classpath/java/awt/LightweightDispatcher.java362
1 files changed, 0 insertions, 362 deletions
diff --git a/libjava/classpath/java/awt/LightweightDispatcher.java b/libjava/classpath/java/awt/LightweightDispatcher.java
deleted file mode 100644
index 11b83d8..0000000
--- a/libjava/classpath/java/awt/LightweightDispatcher.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/* LightweightDispatcher.java -- Dispatches mouse events to lightweights
- Copyright (C) 2006 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath 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 for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package java.awt;
-
-import java.awt.event.InputEvent;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseWheelEvent;
-import java.awt.peer.LightweightPeer;
-import java.util.WeakHashMap;
-
-/**
- * Redispatches mouse events to lightweight components. The native peers know
- * nothing about the lightweight components and thus mouse events are always
- * targetted at Windows or heavyweight components. This class listenes directly
- * on the eventqueue and dispatches mouse events to lightweight components.
- *
- * @author Roman Kennke (kennke@aicas.com)
- */
-final class LightweightDispatcher
-{
-
- /**
- * Maps thread groups to lightweight dispatcher instances. We need to
- * have one instance per thread group so that 2 or more applets or otherwise
- * separated applications (like in OSGI) do not interfer with each other.
- */
- private static WeakHashMap instances = new WeakHashMap();
-
- /**
- * The last mouse event target. If the target changes, additional
- * MOUSE_ENTERED and MOUSE_EXITED events must be dispatched.
- */
- private Component lastTarget;
-
- /**
- * The current mouseEventTarget.
- */
- private Component mouseEventTarget;
-
- /**
- * Returns an instance of LightweightDispatcher for the current thread's
- * thread group.
- *
- * @return an instance of LightweightDispatcher for the current thread's
- * thread group
- */
- static LightweightDispatcher getInstance()
- {
- Thread t = Thread.currentThread();
- ThreadGroup tg = t.getThreadGroup();
- LightweightDispatcher instance = (LightweightDispatcher) instances.get(tg);
- if (instance == null)
- {
- instance = new LightweightDispatcher();
- instances.put(tg, instance);
- }
- return instance;
- }
-
- /**
- * Creates a new LightweightDispatcher. This is private to prevent access
- * from outside. Use {@link #getInstance()} instead.
- */
- private LightweightDispatcher()
- {
- // Nothing to do here.
- }
-
- /**
- * Receives notification if a mouse event passes along the eventqueue.
- *
- * @param event the event
- */
- public boolean dispatchEvent(final AWTEvent event)
- {
- if (event instanceof MouseEvent)
- {
- MouseEvent mouseEvent = (MouseEvent) event;
- return handleMouseEvent(mouseEvent);
- }
- return false;
- }
-
- /**
- * Handles all mouse events that are targetted at toplevel containers
- * (Window instances) and dispatches them to the correct lightweight child.
- *
- * @param ev the mouse event
- * @return whether or not we found a lightweight that handled the event.
- */
- private boolean handleMouseEvent(final MouseEvent ev)
- {
- Container container = (Container) ev.getSource();
- Component target = findTarget(container, ev.getX(), ev.getY());
- trackEnterExit(target, ev);
- int id = ev.getID();
-
- // Dont update the mouseEventTarget when dragging. Also, MOUSE_CLICKED
- // must be dispatched to the original target of MOUSE_PRESSED, so don't
- // update in this case either.
- if (! isDragging(ev) && id != MouseEvent.MOUSE_CLICKED)
- mouseEventTarget = (target != container) ? target : null;
-
- if (mouseEventTarget != null)
- {
- switch (id)
- {
- case MouseEvent.MOUSE_ENTERED:
- case MouseEvent.MOUSE_EXITED:
- // This is already handled in trackEnterExit().
- break;
- case MouseEvent.MOUSE_PRESSED:
- case MouseEvent.MOUSE_RELEASED:
- case MouseEvent.MOUSE_MOVED:
- redispatch(ev, mouseEventTarget, id);
- break;
- case MouseEvent.MOUSE_CLICKED:
- // MOUSE_CLICKED must be dispatched to the original target of
- // MOUSE_PRESSED.
- if (target == mouseEventTarget)
- redispatch(ev, mouseEventTarget, id);
- break;
- case MouseEvent.MOUSE_DRAGGED:
- if (isDragging(ev))
- redispatch(ev, mouseEventTarget, id);
- break;
- case MouseEvent.MOUSE_WHEEL:
- redispatch(ev, mouseEventTarget, id);
- }
- ev.consume();
- }
-
- return ev.isConsumed();
- }
-
- /**
- * Finds the actual target for a mouseevent, starting at <code>c</code>.
- * This searches through the children of the container and finds the first
- * one which is showing, at the location from the mouse event and has
- * a MouseListener or MouseMotionListener attached. If no such child component
- * is found, null is returned.
- *
- * @param c the container to search through
- * @param loc the mouse event point
- *
- * @return the actual receiver of the mouse event, or null, if no such
- * component has been found
- */
- private Component findTarget(final Container c, final int x, final int y)
- {
- Component target = null;
-
- // First we check the children of the container.
-
- // Note: It is important that we use the package private Container
- // fields ncomponents and component here. There are applications
- // that override getComponentCount()
- // and getComponent() to hide internal components, which makes
- // the LightweightDispatcher not work correctly in these cases.
- // As a positive sideeffect this is slightly more efficient.
- int nChildren = c.ncomponents;
- for (int i = 0; i < nChildren && target == null; i++)
- {
- Component child = c.component[i];
- int childX = x - child.x;
- int childY = y - child.y;
- if (child != null && child.visible
- && child.peer instanceof LightweightPeer
- && child.contains(childX, childY))
- {
- // Check if there's a deeper possible target.
- if (child instanceof Container)
- {
- Component deeper = findTarget((Container) child,
- childX, childY);
- if (deeper != null)
- target = deeper;
- }
- // Check if the child itself is interested in mouse events.
- else if (isMouseListening(child))
- target = child;
- }
- }
-
- // Check the container itself, if we didn't find a target yet.
- if (target == null && c.contains(x, y) && isMouseListening(c))
- target = c;
-
- return target;
- }
-
- /**
- * Checks if the specified component would be interested in a mouse event.
- *
- * @param c the component to check
- *
- * @return <code>true</code> if the component has mouse listeners installed,
- * <code>false</code> otherwise
- */
- private boolean isMouseListening(final Component c)
- {
- // Note: It is important to NOT check if the component is listening
- // for a specific event (for instance, mouse motion events). The event
- // gets dispatched to the component if the component is listening
- // for ANY mouse event, even when the component is not listening for the
- // specific type of event. There are applications that depend on this
- // (sadly).
- return c.mouseListener != null
- || c.mouseMotionListener != null
- || c.mouseWheelListener != null
- || (c.eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0
- || (c.eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0
- || (c.eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0;
- }
-
- /**
- * Tracks MOUSE_ENTERED and MOUSE_EXIT as well as MOUSE_MOVED and
- * MOUSE_DRAGGED and creates synthetic MOUSE_ENTERED and MOUSE_EXITED for
- * lightweight component.s
- *
- * @param target the current mouse event target
- * @param ev the mouse event
- */
- private void trackEnterExit(final Component target, final MouseEvent ev)
- {
- int id = ev.getID();
- if (target != lastTarget)
- {
- if (lastTarget != null)
- redispatch(ev, lastTarget, MouseEvent.MOUSE_EXITED);
- if (id == MouseEvent.MOUSE_EXITED)
- ev.consume();
- if (target != null)
- redispatch(ev, target, MouseEvent.MOUSE_ENTERED);
- if (id == MouseEvent.MOUSE_ENTERED)
- ev.consume();
- lastTarget = target;
- }
-
- }
-
- /**
- * Redispatches the specified mouse event to the specified target with the
- * specified id.
- *
- * @param ev the mouse event
- * @param target the new target
- * @param id the new id
- */
- private void redispatch(MouseEvent ev, Component target, int id)
- {
- Component source = ev.getComponent();
- assert target != null;
- if (target.isShowing())
- {
- // Translate coordinates.
- int x = ev.getX();
- int y = ev.getY();
- for (Component c = target; c != null && c != source; c = c.getParent())
- {
- x -= c.x;
- y -= c.y;
- }
-
- // Retarget event.
- MouseEvent retargeted;
- if (id == MouseEvent.MOUSE_WHEEL)
- {
- MouseWheelEvent mwe = (MouseWheelEvent) ev;
- retargeted = new MouseWheelEvent(target, id, ev.getWhen(),
- ev.getModifiers()
- | ev.getModifiersEx(), x, y,
- ev.getClickCount(),
- ev.isPopupTrigger(),
- mwe.getScrollType(),
- mwe.getScrollAmount(),
- mwe.getWheelRotation());
- }
- else
- {
- retargeted = new MouseEvent(target, id, ev.getWhen(),
- ev.getModifiers() | ev.getModifiersEx(),
- x, y, ev.getClickCount(),
- ev.isPopupTrigger(), ev.getButton());
- }
-
- if (target == source)
- ((Container) target).dispatchNoLightweight(retargeted);
- else
- target.dispatchEvent(retargeted);
- }
- }
-
- /**
- * Determines if we are in the middle of a drag operation, that is, if
- * any of the buttons is held down.
- *
- * @param ev the mouse event to check
- *
- * @return <code>true</code> if we are in the middle of a drag operation,
- * <code>false</code> otherwise
- */
- private boolean isDragging(MouseEvent ev)
- {
- int mods = ev.getModifiersEx();
- int id = ev.getID();
- if (id == MouseEvent.MOUSE_PRESSED || id == MouseEvent.MOUSE_RELEASED)
- {
- switch (ev.getButton())
- {
- case MouseEvent.BUTTON1:
- mods ^= InputEvent.BUTTON1_DOWN_MASK;
- break;
- case MouseEvent.BUTTON2:
- mods ^= InputEvent.BUTTON2_DOWN_MASK;
- break;
- case MouseEvent.BUTTON3:
- mods ^= InputEvent.BUTTON3_DOWN_MASK;
- break;
- }
- }
- return (mods & (InputEvent.BUTTON1_DOWN_MASK
- | InputEvent.BUTTON2_DOWN_MASK
- | InputEvent.BUTTON3_DOWN_MASK)) != 0;
- }
-}