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 * @return the event's type id 392 */ 393 public int getID() { 394 return id; 395 } 396 397 /** 398 * Returns a String representation of this object. 399 */ 400 public String toString() { 401 String srcName = null; 402 if (source instanceof Component) { 403 srcName = ((Component)source).getName(); 404 } else if (source instanceof MenuComponent) { 405 srcName = ((MenuComponent)source).getName(); 406 } 407 return getClass().getName() + "[" + paramString() + "] on " + 408 (srcName != null? srcName : source); 409 } 410 411 /** 412 * Returns a string representing the state of this <code>Event</code>. 413 * This method is intended to be used only for debugging purposes, and the 414 * content and format of the returned string may vary between 415 * implementations. The returned string may be empty but may not be 416 * <code>null</code>. 417 * 418 * @return a string representation of this event 419 */ 420 public String paramString() { 421 return ""; 422 } 423 424 /** 425 * Consumes this event, if this event can be consumed. Only low-level, 426 * system events can be consumed 427 */ 428 protected void consume() { 429 switch(id) { 430 case KeyEvent.KEY_PRESSED: 431 case KeyEvent.KEY_RELEASED: 432 case MouseEvent.MOUSE_PRESSED: 433 case MouseEvent.MOUSE_RELEASED: 434 case MouseEvent.MOUSE_MOVED: 435 case MouseEvent.MOUSE_DRAGGED: 436 case MouseEvent.MOUSE_ENTERED: 437 case MouseEvent.MOUSE_EXITED: 438 case MouseEvent.MOUSE_WHEEL: 439 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: 440 case InputMethodEvent.CARET_POSITION_CHANGED: 441 consumed = true; 442 break; 443 default: 444 // event type cannot be consumed 445 } 446 } 447 448 /** 449 * Returns whether this event has been consumed. 450 * @return {@code true} if this event has been consumed; 451 * otherwise {@code false} 452 */ 453 protected boolean isConsumed() { 454 return consumed; 455 } 456 457 /** 458 * Converts a new event to an old one (used for compatibility). 459 * If the new event cannot be converted (because no old equivalent 460 * exists) then this returns null. 461 * 462 * Note: this method is here instead of in each individual new 463 * event class in java.awt.event because we don't want to make 464 * it public and it needs to be called from java.awt. 465 */ 466 Event convertToOld() { 467 Object src = getSource(); 468 int newid = id; 469 470 switch(id) { 471 case KeyEvent.KEY_PRESSED: 472 case KeyEvent.KEY_RELEASED: 473 KeyEvent ke = (KeyEvent)this; 474 if (ke.isActionKey()) { 475 newid = (id == KeyEvent.KEY_PRESSED? 476 Event.KEY_ACTION : Event.KEY_ACTION_RELEASE); 477 } 478 int keyCode = ke.getKeyCode(); 479 if (keyCode == KeyEvent.VK_SHIFT || 480 keyCode == KeyEvent.VK_CONTROL || 481 keyCode == KeyEvent.VK_ALT) { 482 return null; // suppress modifier keys in old event model. 483 } 484 // no mask for button1 existed in old Event - strip it out 485 return new Event(src, ke.getWhen(), newid, 0, 0, 486 Event.getOldEventKey(ke), 487 (ke.getModifiers() & ~InputEvent.BUTTON1_MASK)); 488 489 case MouseEvent.MOUSE_PRESSED: 490 case MouseEvent.MOUSE_RELEASED: 491 case MouseEvent.MOUSE_MOVED: 492 case MouseEvent.MOUSE_DRAGGED: 493 case MouseEvent.MOUSE_ENTERED: 494 case MouseEvent.MOUSE_EXITED: 495 MouseEvent me = (MouseEvent)this; 496 // no mask for button1 existed in old Event - strip it out 497 Event olde = new Event(src, me.getWhen(), newid, 498 me.getX(), me.getY(), 0, 499 (me.getModifiers() & ~InputEvent.BUTTON1_MASK)); 500 olde.clickCount = me.getClickCount(); 501 return olde; 502 503 case FocusEvent.FOCUS_GAINED: 504 return new Event(src, Event.GOT_FOCUS, null); 505 506 case FocusEvent.FOCUS_LOST: 507 return new Event(src, Event.LOST_FOCUS, null); 508 509 case WindowEvent.WINDOW_CLOSING: 510 case WindowEvent.WINDOW_ICONIFIED: 511 case WindowEvent.WINDOW_DEICONIFIED: 512 return new Event(src, newid, null); 513 514 case ComponentEvent.COMPONENT_MOVED: 515 if (src instanceof Frame || src instanceof Dialog) { 516 Point p = ((Component)src).getLocation(); 517 return new Event(src, 0, Event.WINDOW_MOVED, p.x, p.y, 0, 0); 518 } 519 break; 520 521 case ActionEvent.ACTION_PERFORMED: 522 ActionEvent ae = (ActionEvent)this; 523 String cmd; 524 if (src instanceof Button) { 525 cmd = ((Button)src).getLabel(); 526 } else if (src instanceof MenuItem) { 527 cmd = ((MenuItem)src).getLabel(); 528 } else { 529 cmd = ae.getActionCommand(); 530 } 531 return new Event(src, 0, newid, 0, 0, 0, ae.getModifiers(), cmd); 532 533 case ItemEvent.ITEM_STATE_CHANGED: 534 ItemEvent ie = (ItemEvent)this; 535 Object arg; 536 if (src instanceof List) { 537 newid = (ie.getStateChange() == ItemEvent.SELECTED? 538 Event.LIST_SELECT : Event.LIST_DESELECT); 539 arg = ie.getItem(); 540 } else { 541 newid = Event.ACTION_EVENT; 542 if (src instanceof Choice) { 543 arg = ie.getItem(); 544 545 } else { // Checkbox 546 arg = Boolean.valueOf(ie.getStateChange() == ItemEvent.SELECTED); 547 } 548 } 549 return new Event(src, newid, arg); 550 551 case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED: 552 AdjustmentEvent aje = (AdjustmentEvent)this; 553 switch(aje.getAdjustmentType()) { 554 case AdjustmentEvent.UNIT_INCREMENT: 555 newid = Event.SCROLL_LINE_DOWN; 556 break; 557 case AdjustmentEvent.UNIT_DECREMENT: 558 newid = Event.SCROLL_LINE_UP; 559 break; 560 case AdjustmentEvent.BLOCK_INCREMENT: 561 newid = Event.SCROLL_PAGE_DOWN; 562 break; 563 case AdjustmentEvent.BLOCK_DECREMENT: 564 newid = Event.SCROLL_PAGE_UP; 565 break; 566 case AdjustmentEvent.TRACK: 567 if (aje.getValueIsAdjusting()) { 568 newid = Event.SCROLL_ABSOLUTE; 569 } 570 else { 571 newid = Event.SCROLL_END; 572 } 573 break; 574 default: 575 return null; 576 } 577 return new Event(src, newid, Integer.valueOf(aje.getValue())); 578 579 default: 580 } 581 return null; 582 } 583 584 /** 585 * Copies all private data from this event into that. 586 * Space is allocated for the copied data that will be 587 * freed when the that is finalized. Upon completion, 588 * this event is not changed. 589 */ 590 void copyPrivateDataInto(AWTEvent that) { 591 that.bdata = this.bdata; 592 // Copy canAccessSystemClipboard value from this into that. 593 if (this instanceof InputEvent && that instanceof InputEvent) { 594 Field field = get_InputEvent_CanAccessSystemClipboard(); 595 if (field != null) { 596 try { 597 boolean b = field.getBoolean(this); 598 field.setBoolean(that, b); 599 } catch(IllegalAccessException e) { 600 if (log.isLoggable(PlatformLogger.Level.FINE)) { 601 log.fine("AWTEvent.copyPrivateDataInto() got IllegalAccessException ", e); 602 } 603 } 604 } 605 } 606 that.isSystemGenerated = this.isSystemGenerated; 607 } 608 609 void dispatched() { 610 if (this instanceof InputEvent) { 611 Field field = get_InputEvent_CanAccessSystemClipboard(); 612 if (field != null) { 613 try { 614 field.setBoolean(this, false); 615 } catch(IllegalAccessException e) { 616 if (log.isLoggable(PlatformLogger.Level.FINE)) { 617 log.fine("AWTEvent.dispatched() got IllegalAccessException ", e); 618 } 619 } 620 } 621 } 622 } 623 } // class AWTEvent