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 supersede 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 static final long COMPONENT_EVENT_MASK = 0x01; 132 133 /** 134 * The event mask for selecting container events. 135 */ 136 public static final long CONTAINER_EVENT_MASK = 0x02; 137 138 /** 139 * The event mask for selecting focus events. 140 */ 141 public static final long FOCUS_EVENT_MASK = 0x04; 142 143 /** 144 * The event mask for selecting key events. 145 */ 146 public static final long KEY_EVENT_MASK = 0x08; 147 148 /** 149 * The event mask for selecting mouse events. 150 */ 151 public static final long MOUSE_EVENT_MASK = 0x10; 152 153 /** 154 * The event mask for selecting mouse motion events. 155 */ 156 public static final long MOUSE_MOTION_EVENT_MASK = 0x20; 157 158 /** 159 * The event mask for selecting window events. 160 */ 161 public static final long WINDOW_EVENT_MASK = 0x40; 162 163 /** 164 * The event mask for selecting action events. 165 */ 166 public static final long ACTION_EVENT_MASK = 0x80; 167 168 /** 169 * The event mask for selecting adjustment events. 170 */ 171 public static final long ADJUSTMENT_EVENT_MASK = 0x100; 172 173 /** 174 * The event mask for selecting item events. 175 */ 176 public static final long ITEM_EVENT_MASK = 0x200; 177 178 /** 179 * The event mask for selecting text events. 180 */ 181 public static final long TEXT_EVENT_MASK = 0x400; 182 183 /** 184 * The event mask for selecting input method events. 185 */ 186 public static final 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 static final long INPUT_METHODS_ENABLED_MASK = 0x1000; 194 195 /** 196 * The event mask for selecting paint events. 197 */ 198 public static final long PAINT_EVENT_MASK = 0x2000; 199 200 /** 201 * The event mask for selecting invocation events. 202 */ 203 public static final long INVOCATION_EVENT_MASK = 0x4000; 204 205 /** 206 * The event mask for selecting hierarchy events. 207 */ 208 public static final long HIERARCHY_EVENT_MASK = 0x8000; 209 210 /** 211 * The event mask for selecting hierarchy bounds events. 212 */ 213 public static final long HIERARCHY_BOUNDS_EVENT_MASK = 0x10000; 214 215 /** 216 * The event mask for selecting mouse wheel events. 217 * @since 1.4 218 */ 219 public static final long MOUSE_WHEEL_EVENT_MASK = 0x20000; 220 221 /** 222 * The event mask for selecting window state events. 223 * @since 1.4 224 */ 225 public static final long WINDOW_STATE_EVENT_MASK = 0x40000; 226 227 /** 228 * The event mask for selecting window focus events. 229 * @since 1.4 230 */ 231 public static final 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 static final 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 /** 288 * Initialize JNI field and method IDs for fields that may be 289 * accessed from C. 290 */ 291 private static native void initIDs(); 292 293 /** 294 * Constructs an AWTEvent object from the parameters of a 1.0-style event. 295 * 296 * @param event the old-style event 297 * @deprecated It is recommended that {@link #AWTEvent(Object, int)} be used 298 * instead 299 */ 300 @Deprecated(since = "9") 301 public AWTEvent(Event event) { 302 this(event.target, event.id); 303 } 304 305 /** 306 * Constructs an AWTEvent object with the specified source object and type. 307 * 308 * @param source the object where the event originated 309 * @param id the event type 310 */ 311 public AWTEvent(Object source, int id) { 312 super(source); 313 this.id = id; 314 switch(id) { 315 case ActionEvent.ACTION_PERFORMED: 316 case ItemEvent.ITEM_STATE_CHANGED: 317 case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED: 318 case TextEvent.TEXT_VALUE_CHANGED: 319 consumed = true; 320 break; 321 default: 322 } 323 } 324 325 /** 326 * Retargets an event to a new source. This method is typically used to 327 * retarget an event to a lightweight child Component of the original 328 * heavyweight source. 329 * <p> 330 * This method is intended to be used only by event targeting subsystems, 331 * such as client-defined KeyboardFocusManagers. It is not for general 332 * client use. 333 * 334 * @param newSource the new Object to which the event should be dispatched 335 * @since 1.4 336 */ 337 public void setSource(Object newSource) { 338 if (source == newSource) { 339 return; 340 } 341 342 Component comp = null; 343 if (newSource instanceof Component) { 344 comp = (Component)newSource; 345 while (comp != null && comp.peer != null && 346 (comp.peer instanceof LightweightPeer)) { 347 comp = comp.parent; 348 } 349 } 350 351 synchronized (this) { 352 source = newSource; 353 if (comp != null) { 354 ComponentPeer peer = comp.peer; 355 if (peer != null) { 356 nativeSetSource(peer); 357 } 358 } 359 } 360 } 361 362 private native void nativeSetSource(ComponentPeer peer); 363 364 /** 365 * Returns the event type. 366 * 367 * @return the event's type id 368 */ 369 public int getID() { 370 return id; 371 } 372 373 /** 374 * Returns a String representation of this object. 375 */ 376 public String toString() { 377 String srcName = null; 378 if (source instanceof Component) { 379 srcName = ((Component)source).getName(); 380 } else if (source instanceof MenuComponent) { 381 srcName = ((MenuComponent)source).getName(); 382 } 383 return getClass().getName() + "[" + paramString() + "] on " + 384 (srcName != null? srcName : source); 385 } 386 387 /** 388 * Returns a string representing the state of this {@code Event}. 389 * This method is intended to be used only for debugging purposes, and the 390 * content and format of the returned string may vary between 391 * implementations. The returned string may be empty but may not be 392 * {@code null}. 393 * 394 * @return a string representation of this event 395 */ 396 public String paramString() { 397 return ""; 398 } 399 400 /** 401 * Consumes this event, if this event can be consumed. Only low-level, 402 * system events can be consumed 403 */ 404 protected void consume() { 405 switch(id) { 406 case KeyEvent.KEY_PRESSED: 407 case KeyEvent.KEY_RELEASED: 408 case MouseEvent.MOUSE_PRESSED: 409 case MouseEvent.MOUSE_RELEASED: 410 case MouseEvent.MOUSE_MOVED: 411 case MouseEvent.MOUSE_DRAGGED: 412 case MouseEvent.MOUSE_ENTERED: 413 case MouseEvent.MOUSE_EXITED: 414 case MouseEvent.MOUSE_WHEEL: 415 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: 416 case InputMethodEvent.CARET_POSITION_CHANGED: 417 consumed = true; 418 break; 419 default: 420 // event type cannot be consumed 421 } 422 } 423 424 /** 425 * Returns whether this event has been consumed. 426 * 427 * @return {@code true} if this event has been consumed; 428 * otherwise {@code false} 429 */ 430 protected boolean isConsumed() { 431 return consumed; 432 } 433 434 /** 435 * Converts a new event to an old one (used for compatibility). 436 * If the new event cannot be converted (because no old equivalent 437 * exists) then this returns null. 438 * 439 * Note: this method is here instead of in each individual new 440 * event class in java.awt.event because we don't want to make 441 * it public and it needs to be called from java.awt. 442 */ 443 @SuppressWarnings("deprecation") 444 Event convertToOld() { 445 Object src = getSource(); 446 int newid = id; 447 448 switch(id) { 449 case KeyEvent.KEY_PRESSED: 450 case KeyEvent.KEY_RELEASED: 451 KeyEvent ke = (KeyEvent)this; 452 if (ke.isActionKey()) { 453 newid = (id == KeyEvent.KEY_PRESSED? 454 Event.KEY_ACTION : Event.KEY_ACTION_RELEASE); 455 } 456 int keyCode = ke.getKeyCode(); 457 if (keyCode == KeyEvent.VK_SHIFT || 458 keyCode == KeyEvent.VK_CONTROL || 459 keyCode == KeyEvent.VK_ALT) { 460 return null; // suppress modifier keys in old event model. 461 } 462 // no mask for button1 existed in old Event - strip it out 463 return new Event(src, ke.getWhen(), newid, 0, 0, 464 Event.getOldEventKey(ke), 465 (ke.getModifiers() & ~InputEvent.BUTTON1_MASK)); 466 467 case MouseEvent.MOUSE_PRESSED: 468 case MouseEvent.MOUSE_RELEASED: 469 case MouseEvent.MOUSE_MOVED: 470 case MouseEvent.MOUSE_DRAGGED: 471 case MouseEvent.MOUSE_ENTERED: 472 case MouseEvent.MOUSE_EXITED: 473 MouseEvent me = (MouseEvent)this; 474 // no mask for button1 existed in old Event - strip it out 475 Event olde = new Event(src, me.getWhen(), newid, 476 me.getX(), me.getY(), 0, 477 (me.getModifiers() & ~InputEvent.BUTTON1_MASK)); 478 olde.clickCount = me.getClickCount(); 479 return olde; 480 481 case FocusEvent.FOCUS_GAINED: 482 return new Event(src, Event.GOT_FOCUS, null); 483 484 case FocusEvent.FOCUS_LOST: 485 return new Event(src, Event.LOST_FOCUS, null); 486 487 case WindowEvent.WINDOW_CLOSING: 488 case WindowEvent.WINDOW_ICONIFIED: 489 case WindowEvent.WINDOW_DEICONIFIED: 490 return new Event(src, newid, null); 491 492 case ComponentEvent.COMPONENT_MOVED: 493 if (src instanceof Frame || src instanceof Dialog) { 494 Point p = ((Component)src).getLocation(); 495 return new Event(src, 0, Event.WINDOW_MOVED, p.x, p.y, 0, 0); 496 } 497 break; 498 499 case ActionEvent.ACTION_PERFORMED: 500 ActionEvent ae = (ActionEvent)this; 501 String cmd; 502 if (src instanceof Button) { 503 cmd = ((Button)src).getLabel(); 504 } else if (src instanceof MenuItem) { 505 cmd = ((MenuItem)src).getLabel(); 506 } else { 507 cmd = ae.getActionCommand(); 508 } 509 return new Event(src, 0, newid, 0, 0, 0, ae.getModifiers(), cmd); 510 511 case ItemEvent.ITEM_STATE_CHANGED: 512 ItemEvent ie = (ItemEvent)this; 513 Object arg; 514 if (src instanceof List) { 515 newid = (ie.getStateChange() == ItemEvent.SELECTED? 516 Event.LIST_SELECT : Event.LIST_DESELECT); 517 arg = ie.getItem(); 518 } else { 519 newid = Event.ACTION_EVENT; 520 if (src instanceof Choice) { 521 arg = ie.getItem(); 522 523 } else { // Checkbox 524 arg = Boolean.valueOf(ie.getStateChange() == ItemEvent.SELECTED); 525 } 526 } 527 return new Event(src, newid, arg); 528 529 case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED: 530 AdjustmentEvent aje = (AdjustmentEvent)this; 531 switch(aje.getAdjustmentType()) { 532 case AdjustmentEvent.UNIT_INCREMENT: 533 newid = Event.SCROLL_LINE_DOWN; 534 break; 535 case AdjustmentEvent.UNIT_DECREMENT: 536 newid = Event.SCROLL_LINE_UP; 537 break; 538 case AdjustmentEvent.BLOCK_INCREMENT: 539 newid = Event.SCROLL_PAGE_DOWN; 540 break; 541 case AdjustmentEvent.BLOCK_DECREMENT: 542 newid = Event.SCROLL_PAGE_UP; 543 break; 544 case AdjustmentEvent.TRACK: 545 if (aje.getValueIsAdjusting()) { 546 newid = Event.SCROLL_ABSOLUTE; 547 } 548 else { 549 newid = Event.SCROLL_END; 550 } 551 break; 552 default: 553 return null; 554 } 555 return new Event(src, newid, Integer.valueOf(aje.getValue())); 556 557 default: 558 } 559 return null; 560 } 561 562 /** 563 * Copies all private data from this event into that. 564 * Space is allocated for the copied data that will be 565 * freed when the that is finalized. Upon completion, 566 * this event is not changed. 567 */ 568 void copyPrivateDataInto(AWTEvent that) { 569 that.bdata = this.bdata; 570 // Copy canAccessSystemClipboard value from this into that. 571 if (this instanceof InputEvent && that instanceof InputEvent) { 572 573 AWTAccessor.InputEventAccessor accessor 574 = AWTAccessor.getInputEventAccessor(); 575 576 boolean b = accessor.canAccessSystemClipboard((InputEvent) this); 577 accessor.setCanAccessSystemClipboard((InputEvent) that, b); 578 } 579 that.isSystemGenerated = this.isSystemGenerated; 580 } 581 582 void dispatched() { 583 if (this instanceof InputEvent) { 584 AWTAccessor.getInputEventAccessor(). 585 setCanAccessSystemClipboard((InputEvent) this, false); 586 } 587 } 588 } // class AWTEvent