1 /*
2 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.awt.event;
27
28 import java.awt.Event;
29 import java.awt.Component;
30 import java.awt.GraphicsEnvironment;
31 import java.awt.Toolkit;
32 import java.util.Arrays;
33
34 import sun.awt.AWTAccessor;
35 import sun.util.logging.PlatformLogger;
36
37 /**
38 * The root event class for all component-level input events.
39 *
40 * Input events are delivered to listeners before they are
41 * processed normally by the source where they originated.
42 * This allows listeners and component subclasses to "consume"
43 * the event so that the source will not process them in their
44 * default manner. For example, consuming mousePressed events
45 * on a Button component will prevent the Button from being
46 * activated.
47 *
48 * @author Carl Quinn
49 *
50 * @see KeyEvent
51 * @see KeyAdapter
52 * @see MouseEvent
53 * @see MouseAdapter
54 * @see MouseMotionAdapter
55 *
56 * @since 1.1
57 */
58 public abstract class InputEvent extends ComponentEvent {
59
60 private static final PlatformLogger logger = PlatformLogger.getLogger("java.awt.event.InputEvent");
61
62 /**
63 * The Shift key modifier constant.
64 * It is recommended that SHIFT_DOWN_MASK be used instead.
65 */
66 public static final int SHIFT_MASK = Event.SHIFT_MASK;
67
68 /**
69 * The Control key modifier constant.
70 * It is recommended that CTRL_DOWN_MASK be used instead.
71 */
72 public static final int CTRL_MASK = Event.CTRL_MASK;
73
74 /**
75 * The Meta key modifier constant.
76 * It is recommended that META_DOWN_MASK be used instead.
77 */
78 public static final int META_MASK = Event.META_MASK;
79
80 /**
81 * The Alt key modifier constant.
82 * It is recommended that ALT_DOWN_MASK be used instead.
83 */
84 public static final int ALT_MASK = Event.ALT_MASK;
85
86 /**
87 * The AltGraph key modifier constant.
88 */
89 public static final int ALT_GRAPH_MASK = 1 << 5;
90
91 /**
92 * The Mouse Button1 modifier constant.
93 * It is recommended that BUTTON1_DOWN_MASK be used instead.
94 */
95 public static final int BUTTON1_MASK = 1 << 4;
96
97 /**
98 * The Mouse Button2 modifier constant.
99 * It is recommended that BUTTON2_DOWN_MASK be used instead.
100 * Note that BUTTON2_MASK has the same value as ALT_MASK.
101 */
102 public static final int BUTTON2_MASK = Event.ALT_MASK;
103
104 /**
105 * The Mouse Button3 modifier constant.
106 * It is recommended that BUTTON3_DOWN_MASK be used instead.
107 * Note that BUTTON3_MASK has the same value as META_MASK.
108 */
109 public static final int BUTTON3_MASK = Event.META_MASK;
110
111 /**
112 * The Shift key extended modifier constant.
113 * @since 1.4
114 */
115 public static final int SHIFT_DOWN_MASK = 1 << 6;
116
117 /**
118 * The Control key extended modifier constant.
119 * @since 1.4
120 */
121 public static final int CTRL_DOWN_MASK = 1 << 7;
122
123 /**
124 * The Meta key extended modifier constant.
125 * @since 1.4
126 */
127 public static final int META_DOWN_MASK = 1 << 8;
128
129 /**
130 * The Alt key extended modifier constant.
131 * @since 1.4
132 */
133 public static final int ALT_DOWN_MASK = 1 << 9;
134
135 /**
136 * The Mouse Button1 extended modifier constant.
137 * @since 1.4
138 */
139 public static final int BUTTON1_DOWN_MASK = 1 << 10;
140
141 /**
142 * The Mouse Button2 extended modifier constant.
143 * @since 1.4
144 */
145 public static final int BUTTON2_DOWN_MASK = 1 << 11;
146
147 /**
148 * The Mouse Button3 extended modifier constant.
149 * @since 1.4
150 */
151 public static final int BUTTON3_DOWN_MASK = 1 << 12;
152
153 /**
154 * The AltGraph key extended modifier constant.
155 * @since 1.4
156 */
157 public static final int ALT_GRAPH_DOWN_MASK = 1 << 13;
158
159 /**
160 * An array of extended modifiers for additional buttons.
161 * @see getButtonDownMasks
162 * There are twenty buttons fit into 4byte space.
163 * one more bit is reserved for FIRST_HIGH_BIT.
164 * @since 7.0
165 */
166 private static final int [] BUTTON_DOWN_MASK = new int [] { BUTTON1_DOWN_MASK,
167 BUTTON2_DOWN_MASK,
168 BUTTON3_DOWN_MASK,
169 1<<14, //4th phisical button (this is not a wheel!)
170 1<<15, //(this is not a wheel!)
171 1<<16,
172 1<<17,
173 1<<18,
174 1<<19,
175 1<<20,
176 1<<21,
177 1<<22,
178 1<<23,
179 1<<24,
180 1<<25,
181 1<<26,
182 1<<27,
183 1<<28,
184 1<<29,
185 1<<30};
186
187 /**
188 * A method to access an array of extended modifiers for additional buttons.
189 * @since 7.0
190 */
191 private static int [] getButtonDownMasks(){
192 return Arrays.copyOf(BUTTON_DOWN_MASK, BUTTON_DOWN_MASK.length);
193 }
194
195
196 /**
197 * A method to obtain a mask for any existing mouse button.
198 * The returned mask may be used for different purposes. Following are some of them:
199 * <ul>
200 * <li> {@link java.awt.Robot#mousePress(int) mousePress(buttons)} and
201 * {@link java.awt.Robot#mouseRelease(int) mouseRelease(buttons)}
202 * <li> as a {@code modifiers} parameter when creating a new {@link MouseEvent} instance
203 * <li> to check {@link MouseEvent#getModifiersEx() modifiersEx} of existing {@code MouseEvent}
204 * </ul>
205 * @param button is a number to represent a button starting from 1.
206 * For example,
207 * <pre>
208 * int button = InputEvent.getMaskForButton(1);
209 * </pre>
210 * will have the same meaning as
211 * <pre>
212 * int button = InputEvent.getMaskForButton(MouseEvent.BUTTON1);
213 * </pre>
214 * because {@link MouseEvent#BUTTON1 MouseEvent.BUTTON1} equals to 1.
215 * If a mouse has three enabled buttons(see {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()})
216 * then the values from the left column passed into the method will return
217 * corresponding values from the right column:
218 * <PRE>
219 * <b>button </b> <b>returned mask</b>
220 * {@link MouseEvent#BUTTON1 BUTTON1} {@link MouseEvent#BUTTON1_DOWN_MASK BUTTON1_DOWN_MASK}
221 * {@link MouseEvent#BUTTON2 BUTTON2} {@link MouseEvent#BUTTON2_DOWN_MASK BUTTON2_DOWN_MASK}
222 * {@link MouseEvent#BUTTON3 BUTTON3} {@link MouseEvent#BUTTON3_DOWN_MASK BUTTON3_DOWN_MASK}
223 * </PRE>
224 * If a mouse has more than three enabled buttons then more values
225 * are admissible (4, 5, etc.). There is no assigned constants for these extended buttons.
226 * The button masks for the extra buttons returned by this method have no assigned names like the
227 * first three button masks.
228 * <p>
229 * This method has the following implementation restriction.
230 * It returns masks for a limited number of buttons only. The maximum number is
231 * implementation dependent and may vary.
232 * This limit is defined by the relevant number
233 * of buttons that may hypothetically exist on the mouse but it is greater than the
234 * {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}.
235 * <p>
236 * @throws IllegalArgumentException if {@code button} is less than zero or greater than the number
237 * of button masks reserved for buttons
238 * @since 7.0
239 * @see java.awt.MouseInfo#getNumberOfButtons()
240 * @see Toolkit#areExtraMouseButtonsEnabled()
241 * @see MouseEvent#getModifiers()
242 * @see MouseEvent#getModifiersEx()
243 */
244 public static int getMaskForButton(int button) {
245 if (button <= 0 || button > BUTTON_DOWN_MASK.length) {
246 throw new IllegalArgumentException("button doesn\'t exist " + button);
247 }
248 return BUTTON_DOWN_MASK[button - 1];
249 }
250
251 // the constant below MUST be updated if any extra modifier
252 // bits are to be added!
253 // in fact, it is undesirable to add modifier bits
254 // to the same field as this may break applications
255 // see bug# 5066958
256 static final int FIRST_HIGH_BIT = 1 << 31;
257
258 static final int JDK_1_3_MODIFIERS = SHIFT_DOWN_MASK - 1;
259 static final int HIGH_MODIFIERS = ~( FIRST_HIGH_BIT - 1 );
260
261 /**
262 * The input event's Time stamp in UTC format. The time stamp
263 * indicates when the input event was created.
264 *
265 * @serial
266 * @see #getWhen()
267 */
268 long when;
269
270 /**
271 * The state of the modifier mask at the time the input
272 * event was fired.
273 *
274 * @serial
275 * @see #getModifiers()
276 * @see #getModifiersEx()
277 * @see java.awt.event.KeyEvent
278 * @see java.awt.event.MouseEvent
279 */
280 int modifiers;
281
282 /*
283 * A flag that indicates that this instance can be used to access
284 * the system clipboard.
285 */
286 private transient boolean canAccessSystemClipboard;
287
288 static {
289 /* ensure that the necessary native libraries are loaded */
290 NativeLibLoader.loadLibraries();
291 if (!GraphicsEnvironment.isHeadless()) {
292 initIDs();
293 }
294 AWTAccessor.setInputEventAccessor(
295 new AWTAccessor.InputEventAccessor() {
296 public int[] getButtonDownMasks() {
297 return InputEvent.getButtonDownMasks();
298 }
299 });
300 }
301
302 /**
303 * Initialize JNI field and method IDs for fields that may be
304 accessed from C.
305 */
306 private static native void initIDs();
307
308 /**
309 * Constructs an InputEvent object with the specified source component,
310 * modifiers, and type.
311 * <p> This method throws an
312 * <code>IllegalArgumentException</code> if <code>source</code>
313 * is <code>null</code>.
314 *
315 * @param source the object where the event originated
316 * @param id the integer that identifies the event type.
317 * It is allowed to pass as parameter any value that
318 * allowed for some subclass of {@code InputEvent} class.
319 * Passing in the value different from those values result
320 * in unspecified behavior
321 * @param when a long int that gives the time the event occurred.
322 * Passing negative or zero value
323 * is not recommended
324 * @param modifiers a modifier mask describing the modifier keys and mouse
325 * buttons (for example, shift, ctrl, alt, and meta) that
326 * are down during the event.
327 * Only extended modifiers are allowed to be used as a
328 * value for this parameter (see the {@link InputEvent#getModifiersEx}
329 * class for the description of extended modifiers).
330 * Passing negative parameter
331 * is not recommended.
332 * Zero value means that no modifiers were passed
333 * @throws IllegalArgumentException if <code>source</code> is null
334 * @see #getSource()
335 * @see #getID()
336 * @see #getWhen()
337 * @see #getModifiers()
338 */
339 InputEvent(Component source, int id, long when, int modifiers) {
340 super(source, id);
341 this.when = when;
342 this.modifiers = modifiers;
343 canAccessSystemClipboard = canAccessSystemClipboard();
344 }
345
346 private boolean canAccessSystemClipboard() {
347 boolean b = false;
348
349 if (!GraphicsEnvironment.isHeadless()) {
350 SecurityManager sm = System.getSecurityManager();
351 if (sm != null) {
352 try {
353 sm.checkSystemClipboardAccess();
354 b = true;
355 } catch (SecurityException se) {
356 if (logger.isLoggable(PlatformLogger.Level.FINE)) {
357 logger.fine("InputEvent.canAccessSystemClipboard() got SecurityException ", se);
358 }
359 }
360 } else {
361 b = true;
362 }
363 }
364
365 return b;
366 }
367
368 /**
369 * Returns whether or not the Shift modifier is down on this event.
370 */
371 public boolean isShiftDown() {
372 return (modifiers & SHIFT_MASK) != 0;
373 }
374
375 /**
376 * Returns whether or not the Control modifier is down on this event.
377 */
378 public boolean isControlDown() {
379 return (modifiers & CTRL_MASK) != 0;
380 }
381
382 /**
383 * Returns whether or not the Meta modifier is down on this event.
384 */
385 public boolean isMetaDown() {
386 return (modifiers & META_MASK) != 0;
387 }
388
389 /**
390 * Returns whether or not the Alt modifier is down on this event.
391 */
392 public boolean isAltDown() {
393 return (modifiers & ALT_MASK) != 0;
394 }
395
396 /**
397 * Returns whether or not the AltGraph modifier is down on this event.
398 */
399 public boolean isAltGraphDown() {
400 return (modifiers & ALT_GRAPH_MASK) != 0;
401 }
402
403 /**
404 * Returns the difference in milliseconds between the timestamp of when this event occurred and
405 * midnight, January 1, 1970 UTC.
406 */
407 public long getWhen() {
408 return when;
409 }
410
411 /**
412 * Returns the modifier mask for this event.
413 */
414 public int getModifiers() {
415 return modifiers & (JDK_1_3_MODIFIERS | HIGH_MODIFIERS);
416 }
417
418 /**
419 * Returns the extended modifier mask for this event.
420 * <P>
421 * Extended modifiers are the modifiers that ends with the _DOWN_MASK suffix,
422 * such as ALT_DOWN_MASK, BUTTON1_DOWN_MASK, and others.
423 * <P>
424 * Extended modifiers represent the state of all modal keys,
425 * such as ALT, CTRL, META, and the mouse buttons just after
426 * the event occurred.
427 * <P>
428 * For example, if the user presses <b>button 1</b> followed by
429 * <b>button 2</b>, and then releases them in the same order,
430 * the following sequence of events is generated:
431 * <PRE>
432 * <code>MOUSE_PRESSED</code>: <code>BUTTON1_DOWN_MASK</code>
433 * <code>MOUSE_PRESSED</code>: <code>BUTTON1_DOWN_MASK | BUTTON2_DOWN_MASK</code>
434 * <code>MOUSE_RELEASED</code>: <code>BUTTON2_DOWN_MASK</code>
435 * <code>MOUSE_CLICKED</code>: <code>BUTTON2_DOWN_MASK</code>
436 * <code>MOUSE_RELEASED</code>:
437 * <code>MOUSE_CLICKED</code>:
438 * </PRE>
439 * <P>
440 * It is not recommended to compare the return value of this method
441 * using <code>==</code> because new modifiers can be added in the future.
442 * For example, the appropriate way to check that SHIFT and BUTTON1 are
443 * down, but CTRL is up is demonstrated by the following code:
444 * <PRE>
445 * int onmask = SHIFT_DOWN_MASK | BUTTON1_DOWN_MASK;
446 * int offmask = CTRL_DOWN_MASK;
447 * if ((event.getModifiersEx() & (onmask | offmask)) == onmask) {
448 * ...
449 * }
450 * </PRE>
451 * The above code will work even if new modifiers are added.
452 *
453 * @since 1.4
454 */
455 public int getModifiersEx() {
456 return modifiers & ~JDK_1_3_MODIFIERS;
457 }
458
459 /**
460 * Consumes this event so that it will not be processed
461 * in the default manner by the source which originated it.
462 */
463 public void consume() {
464 consumed = true;
465 }
466
467 /**
468 * Returns whether or not this event has been consumed.
469 * @see #consume
470 */
471 public boolean isConsumed() {
472 return consumed;
473 }
474
475 // state serialization compatibility with JDK 1.1
476 static final long serialVersionUID = -2482525981698309786L;
477
478 /**
479 * Returns a String describing the extended modifier keys and
480 * mouse buttons, such as "Shift", "Button1", or "Ctrl+Shift".
481 * These strings can be localized by changing the
482 * <code>awt.properties</code> file.
483 * <p>
484 * Note that passing negative parameter is incorrect,
485 * and will cause the returning an unspecified string.
486 * Zero parameter means that no modifiers were passed and will
487 * cause the returning an empty string.
488 *
489 * @param modifiers a modifier mask describing the extended
490 * modifier keys and mouse buttons for the event
491 * @return a text description of the combination of extended
492 * modifier keys and mouse buttons that were held down
493 * during the event.
494 * @since 1.4
495 */
496 public static String getModifiersExText(int modifiers) {
497 StringBuilder buf = new StringBuilder();
498 if ((modifiers & InputEvent.META_DOWN_MASK) != 0) {
499 buf.append(Toolkit.getProperty("AWT.meta", "Meta"));
500 buf.append("+");
501 }
502 if ((modifiers & InputEvent.CTRL_DOWN_MASK) != 0) {
503 buf.append(Toolkit.getProperty("AWT.control", "Ctrl"));
504 buf.append("+");
505 }
506 if ((modifiers & InputEvent.ALT_DOWN_MASK) != 0) {
507 buf.append(Toolkit.getProperty("AWT.alt", "Alt"));
508 buf.append("+");
509 }
510 if ((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0) {
511 buf.append(Toolkit.getProperty("AWT.shift", "Shift"));
512 buf.append("+");
513 }
514 if ((modifiers & InputEvent.ALT_GRAPH_DOWN_MASK) != 0) {
515 buf.append(Toolkit.getProperty("AWT.altGraph", "Alt Graph"));
516 buf.append("+");
517 }
518
519 int buttonNumber = 1;
520 for (int mask : InputEvent.BUTTON_DOWN_MASK){
521 if ((modifiers & mask) != 0) {
522 buf.append(Toolkit.getProperty("AWT.button"+buttonNumber, "Button"+buttonNumber));
523 buf.append("+");
524 }
525 buttonNumber++;
526 }
527 if (buf.length() > 0) {
528 buf.setLength(buf.length()-1); // remove trailing '+'
529 }
530 return buf.toString();
531 }
532 }
--- EOF ---