/* * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package java.awt.event; import java.awt.Event; import java.awt.Component; import java.awt.GraphicsEnvironment; import java.awt.Toolkit; import java.util.Arrays; import sun.awt.AWTAccessor; import sun.util.logging.PlatformLogger; /** * The root event class for all component-level input events. * * Input events are delivered to listeners before they are * processed normally by the source where they originated. * This allows listeners and component subclasses to "consume" * the event so that the source will not process them in their * default manner. For example, consuming mousePressed events * on a Button component will prevent the Button from being * activated. * * @author Carl Quinn * * @see KeyEvent * @see KeyAdapter * @see MouseEvent * @see MouseAdapter * @see MouseMotionAdapter * * @since 1.1 */ public abstract class InputEvent extends ComponentEvent { private static final PlatformLogger logger = PlatformLogger.getLogger("java.awt.event.InputEvent"); /** * The Shift key modifier constant. * It is recommended that SHIFT_DOWN_MASK be used instead. */ public static final int SHIFT_MASK = Event.SHIFT_MASK; /** * The Control key modifier constant. * It is recommended that CTRL_DOWN_MASK be used instead. */ public static final int CTRL_MASK = Event.CTRL_MASK; /** * The Meta key modifier constant. * It is recommended that META_DOWN_MASK be used instead. */ public static final int META_MASK = Event.META_MASK; /** * The Alt key modifier constant. * It is recommended that ALT_DOWN_MASK be used instead. */ public static final int ALT_MASK = Event.ALT_MASK; /** * The AltGraph key modifier constant. */ public static final int ALT_GRAPH_MASK = 1 << 5; /** * The Mouse Button1 modifier constant. * It is recommended that BUTTON1_DOWN_MASK be used instead. */ public static final int BUTTON1_MASK = 1 << 4; /** * The Mouse Button2 modifier constant. * It is recommended that BUTTON2_DOWN_MASK be used instead. * Note that BUTTON2_MASK has the same value as ALT_MASK. */ public static final int BUTTON2_MASK = Event.ALT_MASK; /** * The Mouse Button3 modifier constant. * It is recommended that BUTTON3_DOWN_MASK be used instead. * Note that BUTTON3_MASK has the same value as META_MASK. */ public static final int BUTTON3_MASK = Event.META_MASK; /** * The Shift key extended modifier constant. * @since 1.4 */ public static final int SHIFT_DOWN_MASK = 1 << 6; /** * The Control key extended modifier constant. * @since 1.4 */ public static final int CTRL_DOWN_MASK = 1 << 7; /** * The Meta key extended modifier constant. * @since 1.4 */ public static final int META_DOWN_MASK = 1 << 8; /** * The Alt key extended modifier constant. * @since 1.4 */ public static final int ALT_DOWN_MASK = 1 << 9; /** * The Mouse Button1 extended modifier constant. * @since 1.4 */ public static final int BUTTON1_DOWN_MASK = 1 << 10; /** * The Mouse Button2 extended modifier constant. * @since 1.4 */ public static final int BUTTON2_DOWN_MASK = 1 << 11; /** * The Mouse Button3 extended modifier constant. * @since 1.4 */ public static final int BUTTON3_DOWN_MASK = 1 << 12; /** * The AltGraph key extended modifier constant. * @since 1.4 */ public static final int ALT_GRAPH_DOWN_MASK = 1 << 13; /** * An array of extended modifiers for additional buttons. * @see getButtonDownMasks * There are twenty buttons fit into 4byte space. * one more bit is reserved for FIRST_HIGH_BIT. * @since 7.0 */ private static final int [] BUTTON_DOWN_MASK = new int [] { BUTTON1_DOWN_MASK, BUTTON2_DOWN_MASK, BUTTON3_DOWN_MASK, 1<<14, //4th phisical button (this is not a wheel!) 1<<15, //(this is not a wheel!) 1<<16, 1<<17, 1<<18, 1<<19, 1<<20, 1<<21, 1<<22, 1<<23, 1<<24, 1<<25, 1<<26, 1<<27, 1<<28, 1<<29, 1<<30}; /** * A method to access an array of extended modifiers for additional buttons. * @since 7.0 */ private static int [] getButtonDownMasks(){ return Arrays.copyOf(BUTTON_DOWN_MASK, BUTTON_DOWN_MASK.length); } /** * A method to obtain a mask for any existing mouse button. * The returned mask may be used for different purposes. Following are some of them: *
* int button = InputEvent.getMaskForButton(1); ** will have the same meaning as *
* int button = InputEvent.getMaskForButton(MouseEvent.BUTTON1); ** because {@link MouseEvent#BUTTON1 MouseEvent.BUTTON1} equals to 1. * If a mouse has three enabled buttons(see {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}) * then the values from the left column passed into the method will return * corresponding values from the right column: *
* button returned mask * {@link MouseEvent#BUTTON1 BUTTON1} {@link MouseEvent#BUTTON1_DOWN_MASK BUTTON1_DOWN_MASK} * {@link MouseEvent#BUTTON2 BUTTON2} {@link MouseEvent#BUTTON2_DOWN_MASK BUTTON2_DOWN_MASK} * {@link MouseEvent#BUTTON3 BUTTON3} {@link MouseEvent#BUTTON3_DOWN_MASK BUTTON3_DOWN_MASK} ** If a mouse has more than three enabled buttons then more values * are admissible (4, 5, etc.). There is no assigned constants for these extended buttons. * The button masks for the extra buttons returned by this method have no assigned names like the * first three button masks. *
* This method has the following implementation restriction. * It returns masks for a limited number of buttons only. The maximum number is * implementation dependent and may vary. * This limit is defined by the relevant number * of buttons that may hypothetically exist on the mouse but it is greater than the * {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}. *
* @throws IllegalArgumentException if {@code button} is less than zero or greater than the number * of button masks reserved for buttons * @since 7.0 * @see java.awt.MouseInfo#getNumberOfButtons() * @see Toolkit#areExtraMouseButtonsEnabled() * @see MouseEvent#getModifiers() * @see MouseEvent#getModifiersEx() */ public static int getMaskForButton(int button) { if (button <= 0 || button > BUTTON_DOWN_MASK.length) { throw new IllegalArgumentException("button doesn\'t exist " + button); } return BUTTON_DOWN_MASK[button - 1]; } // the constant below MUST be updated if any extra modifier // bits are to be added! // in fact, it is undesirable to add modifier bits // to the same field as this may break applications // see bug# 5066958 static final int FIRST_HIGH_BIT = 1 << 31; static final int JDK_1_3_MODIFIERS = SHIFT_DOWN_MASK - 1; static final int HIGH_MODIFIERS = ~( FIRST_HIGH_BIT - 1 ); /** * The input event's Time stamp in UTC format. The time stamp * indicates when the input event was created. * * @serial * @see #getWhen() */ long when; /** * The state of the modifier mask at the time the input * event was fired. * * @serial * @see #getModifiers() * @see #getModifiersEx() * @see java.awt.event.KeyEvent * @see java.awt.event.MouseEvent */ int modifiers; /* * A flag that indicates that this instance can be used to access * the system clipboard. */ private transient boolean canAccessSystemClipboard; static { /* ensure that the necessary native libraries are loaded */ NativeLibLoader.loadLibraries(); if (!GraphicsEnvironment.isHeadless()) { initIDs(); } AWTAccessor.setInputEventAccessor( new AWTAccessor.InputEventAccessor() { public int[] getButtonDownMasks() { return InputEvent.getButtonDownMasks(); } }); } /** * Initialize JNI field and method IDs for fields that may be accessed from C. */ private static native void initIDs(); /** * Constructs an InputEvent object with the specified source component, * modifiers, and type. *
This method throws an
* IllegalArgumentException
if source
* is null
.
*
* @param source the object where the event originated
* @param id the integer that identifies the event type.
* It is allowed to pass as parameter any value that
* allowed for some subclass of {@code InputEvent} class.
* Passing in the value different from those values result
* in unspecified behavior
* @param when a long int that gives the time the event occurred.
* Passing negative or zero value
* is not recommended
* @param modifiers the modifier keys down during event (e.g. shift, ctrl,
* alt, meta)
* Passing negative parameter is not recommended.
* Zero value means no modifiers.
* Either extended _DOWN_MASK or old _MASK modifiers
* should be used, but both models should not be mixed
* in one event. Use of the extended modifiers is
* preferred
* @throws IllegalArgumentException if source
is null
* @see #getSource()
* @see #getID()
* @see #getWhen()
* @see #getModifiers()
*/
InputEvent(Component source, int id, long when, int modifiers) {
super(source, id);
this.when = when;
this.modifiers = modifiers;
canAccessSystemClipboard = canAccessSystemClipboard();
}
private boolean canAccessSystemClipboard() {
boolean b = false;
if (!GraphicsEnvironment.isHeadless()) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
try {
sm.checkSystemClipboardAccess();
b = true;
} catch (SecurityException se) {
if (logger.isLoggable(PlatformLogger.FINE)) {
logger.fine("InputEvent.canAccessSystemClipboard() got SecurityException ", se);
}
}
} else {
b = true;
}
}
return b;
}
/**
* Returns whether or not the Shift modifier is down on this event.
*/
public boolean isShiftDown() {
return (modifiers & SHIFT_MASK) != 0;
}
/**
* Returns whether or not the Control modifier is down on this event.
*/
public boolean isControlDown() {
return (modifiers & CTRL_MASK) != 0;
}
/**
* Returns whether or not the Meta modifier is down on this event.
*/
public boolean isMetaDown() {
return (modifiers & META_MASK) != 0;
}
/**
* Returns whether or not the Alt modifier is down on this event.
*/
public boolean isAltDown() {
return (modifiers & ALT_MASK) != 0;
}
/**
* Returns whether or not the AltGraph modifier is down on this event.
*/
public boolean isAltGraphDown() {
return (modifiers & ALT_GRAPH_MASK) != 0;
}
/**
* Returns the difference in milliseconds between the timestamp of when this event occurred and
* midnight, January 1, 1970 UTC.
*/
public long getWhen() {
return when;
}
/**
* Returns the modifier mask for this event.
*/
public int getModifiers() {
return modifiers & (JDK_1_3_MODIFIERS | HIGH_MODIFIERS);
}
/**
* Returns the extended modifier mask for this event.
* Extended modifiers represent the state of all modal keys,
* such as ALT, CTRL, META, and the mouse buttons just after
* the event occurred
*
* For example, if the user presses button 1 followed by * button 2, and then releases them in the same order, * the following sequence of events is generated: *
**MOUSE_PRESSED
:BUTTON1_DOWN_MASK
*MOUSE_PRESSED
:BUTTON1_DOWN_MASK | BUTTON2_DOWN_MASK
*MOUSE_RELEASED
:BUTTON2_DOWN_MASK
*MOUSE_CLICKED
:BUTTON2_DOWN_MASK
*MOUSE_RELEASED
: *MOUSE_CLICKED
: *
* It is not recommended to compare the return value of this method
* using ==
because new modifiers can be added in the future.
* For example, the appropriate way to check that SHIFT and BUTTON1 are
* down, but CTRL is up is demonstrated by the following code:
*
* int onmask = SHIFT_DOWN_MASK | BUTTON1_DOWN_MASK; * int offmask = CTRL_DOWN_MASK; * if ((event.getModifiersEx() & (onmask | offmask)) == onmask) { * ... * } ** The above code will work even if new modifiers are added. * * @since 1.4 */ public int getModifiersEx() { return modifiers & ~JDK_1_3_MODIFIERS; } /** * Consumes this event so that it will not be processed * in the default manner by the source which originated it. */ public void consume() { consumed = true; } /** * Returns whether or not this event has been consumed. * @see #consume */ public boolean isConsumed() { return consumed; } // state serialization compatibility with JDK 1.1 static final long serialVersionUID = -2482525981698309786L; /** * Returns a String describing the extended modifier keys and * mouse buttons, such as "Shift", "Button1", or "Ctrl+Shift". * These strings can be localized by changing the *
awt.properties
file.
* * Note that passing negative parameter is incorrect, * and will cause the returning an unspecified string. * Zero parameter means that no modifiers were passed and will * cause the returning an empty string. * * @param modifiers a modifier mask describing the extended * modifier keys and mouse buttons for the event * @return a text description of the combination of extended * modifier keys and mouse buttons that were held down * during the event. * @since 1.4 */ public static String getModifiersExText(int modifiers) { StringBuilder buf = new StringBuilder(); if ((modifiers & InputEvent.META_DOWN_MASK) != 0) { buf.append(Toolkit.getProperty("AWT.meta", "Meta")); buf.append("+"); } if ((modifiers & InputEvent.CTRL_DOWN_MASK) != 0) { buf.append(Toolkit.getProperty("AWT.control", "Ctrl")); buf.append("+"); } if ((modifiers & InputEvent.ALT_DOWN_MASK) != 0) { buf.append(Toolkit.getProperty("AWT.alt", "Alt")); buf.append("+"); } if ((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0) { buf.append(Toolkit.getProperty("AWT.shift", "Shift")); buf.append("+"); } if ((modifiers & InputEvent.ALT_GRAPH_DOWN_MASK) != 0) { buf.append(Toolkit.getProperty("AWT.altGraph", "Alt Graph")); buf.append("+"); } int buttonNumber = 1; for (int mask : InputEvent.BUTTON_DOWN_MASK){ if ((modifiers & mask) != 0) { buf.append(Toolkit.getProperty("AWT.button"+buttonNumber, "Button"+buttonNumber)); buf.append("+"); } buttonNumber++; } if (buf.length() > 0) { buf.setLength(buf.length()-1); // remove trailing '+' } return buf.toString(); } }