/* Copyright (C) 2006 Christian Schneider
*
* This file is part of Nomad.
*
* Nomad 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 of the License, or
* (at your option) any later version.
*
* Nomad 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 Nomad; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.sf.nmedit.jtheme.util;
import java.awt.Component;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.SwingUtilities;
import javax.swing.event.MenuDragMouseEvent;
import javax.swing.event.MouseInputListener;
public class RetargetMouseEventSupport implements MouseInputListener, MouseWheelListener
{
private boolean isDragging = false;
private transient Component mouseEventTarget;
private Component dragTarget;
private Component retargetSource;
private RetargetMouseEventSupport(Component retargetSource)
{
this.retargetSource = retargetSource;
}
private static RetargetMouseEventSupport TO_PARENT = new RetargetMouseEventSupport(null);
public static RetargetMouseEventSupport retargetToParent(Component c)
{
return TO_PARENT;
}
public static RetargetMouseEventSupport createSupport(Component c)
{
return new RetargetMouseEventSupport(c);
}
public void mouseClicked(MouseEvent e)
{
handleEvent(e);
}
public void mouseEntered(MouseEvent e)
{
handleEvent(e);
}
public void mouseExited(MouseEvent e)
{
handleEvent(e);
}
public void mousePressed(MouseEvent e)
{
handleEvent(e);
}
public void mouseReleased(MouseEvent e)
{
handleEvent(e);
}
public void mouseDragged(MouseEvent e)
{
handleEvent(e);
}
public void mouseMoved(MouseEvent e)
{
handleEvent(e);
}
public void mouseWheelMoved(MouseWheelEvent e)
{
handleEvent(e);
}
protected Component getTarget(MouseEvent e)
{
Component c = e.getComponent();
return c.getParent();
}
private void handleEvent(MouseEvent e)
{
Component target = getTarget(e);
if (target == null) return;
int id = e.getID();
switch (id)
{
case MouseEvent.MOUSE_ENTERED:
if (!isDragging)
{
mouseEventTarget = target;
redispatch(id, e, mouseEventTarget);
}
break;
case MouseEvent.MOUSE_EXITED:
if (!isDragging)
{
redispatch(id, e, mouseEventTarget);
}
break;
case MouseEvent.MOUSE_PRESSED:
mouseEventTarget = target;
redispatch(id, e, mouseEventTarget);
// Start dragging.
dragTarget = target;
break;
case MouseEvent.MOUSE_RELEASED:
if (isDragging)
{
redispatch(id, e, dragTarget);
isDragging = false;
}
else
redispatch(id, e, mouseEventTarget);
break;
case MouseEvent.MOUSE_CLICKED:
redispatch(id, e, mouseEventTarget);
break;
case MouseEvent.MOUSE_MOVED:
if (target != mouseEventTarget)
{
// Create additional MOUSE_EXITED/MOUSE_ENTERED pairs.
redispatch(MouseEvent.MOUSE_EXITED, e, mouseEventTarget);
mouseEventTarget = target;
redispatch(MouseEvent.MOUSE_ENTERED, e, mouseEventTarget);
}
redispatch(id, e, mouseEventTarget);
break;
case MouseEvent.MOUSE_DRAGGED:
if (! isDragging) isDragging = true;
redispatch(id, e, mouseEventTarget);
break;
case MouseEvent.MOUSE_WHEEL:
redispatch(id, e, mouseEventTarget);
break;
default:
break;
}
}
private void redispatch(int id, MouseEvent e, Component target)
{
if (target == null) // just in case
return;
Component source = retargetSource;
if (source == null)
source = e.getComponent();
Point p = SwingUtilities.convertPoint(source, e.getX(), e.getY(), target);
if (e instanceof MouseWheelEvent)
{
MouseWheelEvent w = (MouseWheelEvent) e;
MouseEvent ev = new MouseWheelEvent(target, id, e.getWhen(),
e.getModifiers() | e.getModifiersEx(),
p.x, p.y, e.getClickCount(),
e.isPopupTrigger(),
w.getScrollType(),
w.getScrollAmount(),
w.getWheelRotation());
target.dispatchEvent(ev);
}
else if (e instanceof MenuDragMouseEvent) {
// no op
}
else if (e instanceof MouseEvent)
{
MouseEvent ev = new MouseEvent(target, id, e.getWhen(),
e.getModifiers() | e.getModifiersEx(),
p.x, p.y, e.getClickCount(),
e.isPopupTrigger());
target.dispatchEvent(ev);
}
}
public void install(Component c)
{
c.addMouseListener(this);
c.addMouseMotionListener(this);
c.addMouseWheelListener(this);
}
public void uninstall(Component c)
{
c.removeMouseListener(this);
c.removeMouseMotionListener(this);
c.removeMouseWheelListener(this);
}
}