LightweightRedirector.java [plain text]
package gnu.awt;
import java.awt.AWTEvent;
import java.awt.AWTError;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.MouseEvent;
import java.awt.event.InputEvent;
public class LightweightRedirector
{
final static int LAST_BUTTON_NUMBER = 3;
Component[] releaseTargets = new Component[LAST_BUTTON_NUMBER+1];
public AWTEvent redirect(AWTEvent event)
{
if (event instanceof MouseEvent)
return redirectMouse((MouseEvent) event);
return event;
}
MouseEvent redirectMouse(MouseEvent event)
{
int button = getButtonNumber(event);
int id = event.getID();
Component heavySource = (Component) event.getSource();
Component source = heavySource;
int x = event.getX();
int y = event.getY();
if (id == MouseEvent.MOUSE_RELEASED)
{
Component target = releaseTargets[button];
if (target != null)
{
releaseTargets[button] = null;
source = target;
Component child = source;
while (child != heavySource)
{
x -= child.getX();
y -= child.getY();
child = child.getParent();
if (child == null)
System.err.println("warning, orphaned release target");
}
}
}
else
{
while (true)
{
Component parent = source;
Component child = parent.getComponentAt(x, y);
if (parent == child)
break;
if (child == null)
{
String msg = "delivered event not within component. " +
"Heavyweight source was " + heavySource + ". " +
"Component was " + parent;
throw new AWTError(msg);
}
if (child.isLightweight())
{
source = child;
x -= child.getX();
y -= child.getY();
}
else
{
System.err.println("warning: event delivered to wrong " +
"heavyweight component. Was " +
"delivered to " + source + ". " +
"Should have been delivered to " +
child + ". Maybe the native window " +
"system is bubbling events up the " +
"containment hierarchy.");
break;
}
}
if (id == MouseEvent.MOUSE_PRESSED)
releaseTargets[button] = source;
}
if (source == heavySource)
return event;
if (!source.isLightweight())
System.err.println("warning: redirecting to heavyweight");
MouseEvent redirected = new MouseEvent(source, event.getID(),
event.getWhen(),
event.getModifiersEx(),
x, y,
event.getClickCount(),
event.isPopupTrigger());
return redirected;
}
int getButtonNumber(InputEvent event)
{
int modifiers = event.getModifiersEx();
modifiers &=
InputEvent.BUTTON1_DOWN_MASK |
InputEvent.BUTTON2_DOWN_MASK |
InputEvent.BUTTON3_DOWN_MASK;
switch (modifiers)
{
case InputEvent.BUTTON1_DOWN_MASK:
return 1;
case InputEvent.BUTTON2_DOWN_MASK:
return 2;
case InputEvent.BUTTON3_DOWN_MASK:
return 3;
case 0:
return 0;
default:
System.err.println("FIXME: multibutton event");
return 0;
}
}
}