1 /* 2 * Copyright (c) 1996, 2014, 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; 27 28 import java.util.EventObject; 29 import java.awt.event.*; 30 import java.awt.peer.ComponentPeer; 31 import java.awt.peer.LightweightPeer; 32 import java.lang.reflect.Field; 33 import sun.awt.AWTAccessor; 34 import sun.util.logging.PlatformLogger; 35 36 import java.security.AccessControlContext; 37 import java.security.AccessController; 38 39 /** 40 * The root event class for all AWT events. 41 * This class and its subclasses supercede the original 42 * java.awt.Event class. 43 * Subclasses of this root AWTEvent class defined outside of the 44 * java.awt.event package should define event ID values greater than 45 * the value defined by RESERVED_ID_MAX. 46 * <p> 47 * The event masks defined in this class are needed by Component subclasses 48 * which are using Component.enableEvents() to select for event types not 49 * selected by registered listeners. If a listener is registered on a 50 * component, the appropriate event mask is already set internally by the 51 * component. 52 * <p> 53 * The masks are also used to specify to which types of events an 54 * AWTEventListener should listen. The masks are bitwise-ORed together 55 * and passed to Toolkit.addAWTEventListener. 56 * 57 * @see Component#enableEvents 58 * @see Toolkit#addAWTEventListener 59 * 60 * @see java.awt.event.ActionEvent 61 * @see java.awt.event.AdjustmentEvent 62 * @see java.awt.event.ComponentEvent 63 * @see java.awt.event.ContainerEvent 64 * @see java.awt.event.FocusEvent 65 * @see java.awt.event.InputMethodEvent 66 * @see java.awt.event.InvocationEvent 67 * @see java.awt.event.ItemEvent 68 * @see java.awt.event.HierarchyEvent 69 * @see java.awt.event.KeyEvent 70 * @see java.awt.event.MouseEvent 71 * @see java.awt.event.MouseWheelEvent 72 * @see java.awt.event.PaintEvent 73 * @see java.awt.event.TextEvent 74 * @see java.awt.event.WindowEvent 75 * 76 * @author Carl Quinn 77 * @author Amy Fowler 78 * @since 1.1 79 */ 80 public abstract class AWTEvent extends EventObject { 81 private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.AWTEvent"); 82 private byte bdata[]; 83 84 /** 85 * The event's id. 86 * @serial 87 * @see #getID() 88 * @see #AWTEvent 89 */ 90 protected int id; 91 92 /** 93 * Controls whether or not the event is sent back down to the peer once the 94 * source has processed it - false means it's sent to the peer; true means 95 * it's not. Semantic events always have a 'true' value since they were 96 * generated by the peer in response to a low-level event. 97 * @serial 98 * @see #consume 99 * @see #isConsumed 100 */ 101 protected boolean consumed = false; 102 103 /* 104 * The event's AccessControlContext. 105 */ 106 private transient volatile AccessControlContext acc = 107 AccessController.getContext(); 108 109 /* 110 * Returns the acc this event was constructed with. 111 */ 112 final AccessControlContext getAccessControlContext() { 113 if (acc == null) { 114 throw new SecurityException("AWTEvent is missing AccessControlContext"); 115 } 116 return acc; 117 } 118 119 transient boolean focusManagerIsDispatching = false; 120 transient boolean isPosted; 121 122 /** 123 * Indicates whether this AWTEvent was generated by the system as 124 * opposed to by user code. 125 */ 126 private transient boolean isSystemGenerated; 127 128 /** 129 * The event mask for selecting component events. 130 */ 131 public final static long COMPONENT_EVENT_MASK = 0x01; 132 133 /** 134 * The event mask for selecting container events. 135 */ 136 public final static long CONTAINER_EVENT_MASK = 0x02; 137 138 /** 139 * The event mask for selecting focus events. 140 */ 141 public final static long FOCUS_EVENT_MASK = 0x04; 142 143 /** 144 * The event mask for selecting key events. 145 */ 146 public final static long KEY_EVENT_MASK = 0x08; 147 148 /** 149 * The event mask for selecting mouse events. 150 */ 151 public final static long MOUSE_EVENT_MASK = 0x10; 152 153 /** 154 * The event mask for selecting mouse motion events. 155 */ 156 public final static long MOUSE_MOTION_EVENT_MASK = 0x20; 157 158 /** 159 * The event mask for selecting window events. 160 */ 161 public final static long WINDOW_EVENT_MASK = 0x40; 162 163 /** 164 * The event mask for selecting action events. 165 */ 166 public final static long ACTION_EVENT_MASK = 0x80; 167 168 /** 169 * The event mask for selecting adjustment events. 170 */ 171 public final static long ADJUSTMENT_EVENT_MASK = 0x100; 172 173 /** 174 * The event mask for selecting item events. 175 */ 176 public final static long ITEM_EVENT_MASK = 0x200; 177 178 /** 179 * The event mask for selecting text events. 180 */ 181 public final static long TEXT_EVENT_MASK = 0x400; 182 183 /** 184 * The event mask for selecting input method events. 185 */ 186 public final static long INPUT_METHOD_EVENT_MASK = 0x800; 187 188 /** 189 * The pseudo event mask for enabling input methods. 190 * We're using one bit in the eventMask so we don't need 191 * a separate field inputMethodsEnabled. 192 */ 193 final static long INPUT_METHODS_ENABLED_MASK = 0x1000; 194 195 /** 196 * The event mask for selecting paint events. 197 */ 198 public final static long PAINT_EVENT_MASK = 0x2000; 199 200 /** 201 * The event mask for selecting invocation events. 202 */ 203 public final static long INVOCATION_EVENT_MASK = 0x4000; 204 205 /** 206 * The event mask for selecting hierarchy events. 207 */ 208 public final static long HIERARCHY_EVENT_MASK = 0x8000; 209 210 /** 211 * The event mask for selecting hierarchy bounds events. 212 */ 213 public final static long HIERARCHY_BOUNDS_EVENT_MASK = 0x10000; 214 215 /** 216 * The event mask for selecting mouse wheel events. 217 * @since 1.4 218 */ 219 public final static long MOUSE_WHEEL_EVENT_MASK = 0x20000; 220 221 /** 222 * The event mask for selecting window state events. 223 * @since 1.4 224 */ 225 public final static long WINDOW_STATE_EVENT_MASK = 0x40000; 226 227 /** 228 * The event mask for selecting window focus events. 229 * @since 1.4 230 */ 231 public final static long WINDOW_FOCUS_EVENT_MASK = 0x80000; 232 233 /** 234 * WARNING: there are more mask defined privately. See 235 * SunToolkit.GRAB_EVENT_MASK. 236 */ 237 238 /** 239 * The maximum value for reserved AWT event IDs. Programs defining 240 * their own event IDs should use IDs greater than this value. 241 */ 242 public final static int RESERVED_ID_MAX = 1999; 243 244 // security stuff 245 private static Field inputEvent_CanAccessSystemClipboard_Field = null; 246 247 /* 248 * JDK 1.1 serialVersionUID 249 */ 250 private static final long serialVersionUID = -1825314779160409405L; 251 252 static { 253 /* ensure that the necessary native libraries are loaded */ 254 Toolkit.loadLibraries(); 255 if (!GraphicsEnvironment.isHeadless()) { 256 initIDs(); 257 } 258 AWTAccessor.setAWTEventAccessor( 259 new AWTAccessor.AWTEventAccessor() { 260 public void setPosted(AWTEvent ev) { 261 ev.isPosted = true; 262 } 263 264 public void setSystemGenerated(AWTEvent ev) { 265 ev.isSystemGenerated = true; 266 } 267 268 public boolean isSystemGenerated(AWTEvent ev) { 269 return ev.isSystemGenerated; 270 } 271 272 public AccessControlContext getAccessControlContext(AWTEvent ev) { 273 return ev.getAccessControlContext(); 274 } 275 276 public byte[] getBData(AWTEvent ev) { 277 return ev.bdata; 278 } 279 280 public void setBData(AWTEvent ev, byte[] bdata) { 281 ev.bdata = bdata; 282 } 283 284 }); 285 } 286 287 private static synchronized Field get_InputEvent_CanAccessSystemClipboard() { 288 if (inputEvent_CanAccessSystemClipboard_Field == null) { 289 inputEvent_CanAccessSystemClipboard_Field = 290 java.security.AccessController.doPrivileged( 291 new java.security.PrivilegedAction<Field>() { 292 public Field run() { 293 Field field = null; 294 try { 295 field = InputEvent.class. 296 getDeclaredField("canAccessSystemClipboard"); 297 field.setAccessible(true); 298 return field; 299 } catch (SecurityException e) { 300 if (log.isLoggable(PlatformLogger.Level.FINE)) { 301 log.fine("AWTEvent.get_InputEvent_CanAccessSystemClipboard() got SecurityException ", e); 302 } 303 } catch (NoSuchFieldException e) { 304 if (log.isLoggable(PlatformLogger.Level.FINE)) { 305 log.fine("AWTEvent.get_InputEvent_CanAccessSystemClipboard() got NoSuchFieldException ", e); 306 } 307 } 308 return null; 309 } 310 }); 311 } 312 313 return inputEvent_CanAccessSystemClipboard_Field; 314 } 315 316 /** 317 * Initialize JNI field and method IDs for fields that may be 318 * accessed from C. 319 */ 320 private static native void initIDs(); 321 322 /** 323 * Constructs an AWTEvent object from the parameters of a 1.0-style event. 324 * @param event the old-style event 325 */ 326 public AWTEvent(Event event) { 327 this(event.target, event.id); 328 } 329 330 /** 331 * Constructs an AWTEvent object with the specified source object and type. 332 * 333 * @param source the object where the event originated 334 * @param id the event type 335 */ 336 public AWTEvent(Object source, int id) { 337 super(source); 338 this.id = id; 339 switch(id) { 340 case ActionEvent.ACTION_PERFORMED: 341 case ItemEvent.ITEM_STATE_CHANGED: 342 case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED: 343 case TextEvent.TEXT_VALUE_CHANGED: 344 consumed = true; 345 break; 346 default: 347 } 348 } 349 350 /** 351 * Retargets an event to a new source. This method is typically used to 352 * retarget an event to a lightweight child Component of the original 353 * heavyweight source. 354 * <p> 355 * This method is intended to be used only by event targeting subsystems, 356 * such as client-defined KeyboardFocusManagers. It is not for general 357 * client use. 358 * 359 * @param newSource the new Object to which the event should be dispatched 360 * @since 1.4 361 */ 362 public void setSource(Object newSource) { 363 if (source == newSource) { 364 return; 365 } 366 367 Component comp = null; 368 if (newSource instanceof Component) { 369 comp = (Component)newSource; 370 while (comp != null && comp.peer != null && 371 (comp.peer instanceof LightweightPeer)) { 372 comp = comp.parent; 373 } 374 } 375 376 synchronized (this) { 377 source = newSource; 378 if (comp != null) { 379 ComponentPeer peer = comp.peer; 380 if (peer != null) { 381 nativeSetSource(peer); 382 } 383 } 384 } 385 } 386 387 private native void nativeSetSource(ComponentPeer peer); 388 389 /** 390 * Returns the event type. 391 * 392 * @return the event's type id 393 */ 394 public int getID() { 395 return id; 396 } 397 398 /** 399 * Returns a String representation of this object. 400 */ 401 public String toString() { 402 String srcName = null; 403 if (source instanceof Component) { 404 srcName = ((Component)source).getName(); 405 } else if (source instanceof MenuComponent) { 406 srcName = ((MenuComponent)source).getName(); 407 } 408 return getClass().getName() + "[" + paramString() + "] on " + 409 (srcName != null? srcName : source); 410 } 411 412 /** 413 * Returns a string representing the state of this <code>Event</code>. 414 * This method is intended to be used only for debugging purposes, and the 415 * content and format of the returned string may vary between 416 * implementations. The returned string may be empty but may not be 417 * <code>null</code>. 418 * 419 * @return a string representation of this event 420 */ 421 public String paramString() { 422 return ""; 423 } 424 425 /** 426 * Consumes this event, if this event can be consumed. Only low-level, 427 * system events can be consumed 428 */ 429 protected void consume() { 430 switch(id) { 431 case KeyEvent.KEY_PRESSED: 432 case KeyEvent.KEY_RELEASED: 433 case MouseEvent.MOUSE_PRESSED: 434 case MouseEvent.MOUSE_RELEASED: 435 case MouseEvent.MOUSE_MOVED: 436 case MouseEvent.MOUSE_DRAGGED: 437 case MouseEvent.MOUSE_ENTERED: 438 case MouseEvent.MOUSE_EXITED: 439 case MouseEvent.MOUSE_WHEEL: 440 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: 441 case InputMethodEvent.CARET_POSITION_CHANGED: 442 consumed = true; 443 break; 444 default: 445 // event type cannot be consumed 446 } 447 } 448 449 /** 450 * Returns whether this event has been consumed. 451 * 452 * @return {@code true} if this event has been consumed; 453 * otherwise {@code false} 454 */ 455 protected boolean isConsumed() { 456 return consumed; 457 } 458 459 /** 460 * Converts a new event to an old one (used for compatibility). 461 * If the new event cannot be converted (because no old equivalent 462 * exists) then this returns null. 463 * 464 * Note: this method is here instead of in each individual new 465 * event class in java.awt.event because we don't want to make 466 * it public and it needs to be called from java.awt. 467 */ 468 Event convertToOld() { 469 Object src = getSource(); 470 int newid = id; 471 472 switch(id) { 473 case KeyEvent.KEY_PRESSED: 474 case KeyEvent.KEY_RELEASED: 475 KeyEvent ke = (KeyEvent)this; 476 if (ke.isActionKey()) { 477 newid = (id == KeyEvent.KEY_PRESSED? 478 Event.KEY_ACTION : Event.KEY_ACTION_RELEASE); 479 } 480 int keyCode = ke.getKeyCode(); 481 if (keyCode == KeyEvent.VK_SHIFT || 482 keyCode == KeyEvent.VK_CONTROL || 483 keyCode == KeyEvent.VK_ALT) { 484 return null; // suppress modifier keys in old event model. 485 } 486 // no mask for button1 existed in old Event - strip it out 487 return new Event(src, ke.getWhen(), newid, 0, 0, 488 Event.getOldEventKey(ke), 489 (ke.getModifiers() & ~InputEvent.BUTTON1_MASK)); 490 491 case MouseEvent.MOUSE_PRESSED: 492 case MouseEvent.MOUSE_RELEASED: 493 case MouseEvent.MOUSE_MOVED: 494 case MouseEvent.MOUSE_DRAGGED: 495 case MouseEvent.MOUSE_ENTERED: 496 case MouseEvent.MOUSE_EXITED: 497 MouseEvent me = (MouseEvent)this; 498 // no mask for button1 existed in old Event - strip it out 499 Event olde = new Event(src, me.getWhen(), newid, 500 me.getX(), me.getY(), 0, 501 (me.getModifiers() & ~InputEvent.BUTTON1_MASK)); 502 olde.clickCount = me.getClickCount(); 503 return olde; 504 505 case FocusEvent.FOCUS_GAINED: 506 return new Event(src, Event.GOT_FOCUS, null); 507 508 case FocusEvent.FOCUS_LOST: 509 return new Event(src, Event.LOST_FOCUS, null); 510 511 case WindowEvent.WINDOW_CLOSING: 512 case WindowEvent.WINDOW_ICONIFIED: 513 case WindowEvent.WINDOW_DEICONIFIED: 514 return new Event(src, newid, null); 515 516 case ComponentEvent.COMPONENT_MOVED: 517 if (src instanceof Frame || src instanceof Dialog) { 518 Point p = ((Component)src).getLocation(); 519 return new Event(src, 0, Event.WINDOW_MOVED, p.x, p.y, 0, 0); 520 } 521 break; 522 523 case ActionEvent.ACTION_PERFORMED: 524 ActionEvent ae = (ActionEvent)this; 525 String cmd; 526 if (src instanceof Button) { 527 cmd = ((Button)src).getLabel(); 528 } else if (src instanceof MenuItem) { 529 cmd = ((MenuItem)src).getLabel(); 530 } else { 531 cmd = ae.getActionCommand(); 532 } 533 return new Event(src, 0, newid, 0, 0, 0, ae.getModifiers(), cmd); 534 535 case ItemEvent.ITEM_STATE_CHANGED: 536 ItemEvent ie = (ItemEvent)this; 537 Object arg; 538 if (src instanceof List) { 539 newid = (ie.getStateChange() == ItemEvent.SELECTED? 540 Event.LIST_SELECT : Event.LIST_DESELECT); 541 arg = ie.getItem(); 542 } else { 543 newid = Event.ACTION_EVENT; 544 if (src instanceof Choice) { 545 arg = ie.getItem(); 546 547 } else { // Checkbox 548 arg = Boolean.valueOf(ie.getStateChange() == ItemEvent.SELECTED); 549 } 550 } 551 return new Event(src, newid, arg); 552 553 case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED: 554 AdjustmentEvent aje = (AdjustmentEvent)this; 555 switch(aje.getAdjustmentType()) { 556 case AdjustmentEvent.UNIT_INCREMENT: 557 newid = Event.SCROLL_LINE_DOWN; 558 break; 559 case AdjustmentEvent.UNIT_DECREMENT: 560 newid = Event.SCROLL_LINE_UP; 561 break; 562 case AdjustmentEvent.BLOCK_INCREMENT: 563 newid = Event.SCROLL_PAGE_DOWN; 564 break; 565 case AdjustmentEvent.BLOCK_DECREMENT: 566 newid = Event.SCROLL_PAGE_UP; 567 break; 568 case AdjustmentEvent.TRACK: 569 if (aje.getValueIsAdjusting()) { 570 newid = Event.SCROLL_ABSOLUTE; 571 } 572 else { 573 newid = Event.SCROLL_END; 574 } 575 break; 576 default: 577 return null; 578 } 579 return new Event(src, newid, Integer.valueOf(aje.getValue())); 580 581 default: 582 } 583 return null; 584 } 585 586 /** 587 * Copies all private data from this event into that. 588 * Space is allocated for the copied data that will be 589 * freed when the that is finalized. Upon completion, 590 * this event is not changed. 591 */ 592 void copyPrivateDataInto(AWTEvent that) { 593 that.bdata = this.bdata; 594 // Copy canAccessSystemClipboard value from this into that. 595 if (this instanceof InputEvent && that instanceof InputEvent) { 596 Field field = get_InputEvent_CanAccessSystemClipboard(); 597 if (field != null) { 598 try { 599 boolean b = field.getBoolean(this); 600 field.setBoolean(that, b); 601 } catch(IllegalAccessException e) { 602 if (log.isLoggable(PlatformLogger.Level.FINE)) { 603 log.fine("AWTEvent.copyPrivateDataInto() got IllegalAccessException ", e); 604 } 605 } 606 } 607 } 608 that.isSystemGenerated = this.isSystemGenerated; 609 } 610 611 void dispatched() { 612 if (this instanceof InputEvent) { 613 Field field = get_InputEvent_CanAccessSystemClipboard(); 614 if (field != null) { 615 try { 616 field.setBoolean(this, false); 617 } catch(IllegalAccessException e) { 618 if (log.isLoggable(PlatformLogger.Level.FINE)) { 619 log.fine("AWTEvent.dispatched() got IllegalAccessException ", e); 620 } 621 } 622 } 623 } 624 } 625 } // class AWTEvent