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