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 * @param event the old-style event 296 */ 297 public AWTEvent(Event event) { 298 this(event.target, event.id); 299 } 300 301 /** 302 * Constructs an AWTEvent object with the specified source object and type. 303 * 304 * @param source the object where the event originated 305 * @param id the event type 306 */ 307 public AWTEvent(Object source, int id) { 308 super(source); 309 this.id = id; 310 switch(id) { 311 case ActionEvent.ACTION_PERFORMED: 312 case ItemEvent.ITEM_STATE_CHANGED: 313 case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED: 314 case TextEvent.TEXT_VALUE_CHANGED: 315 consumed = true; 316 break; 317 default: 318 } 319 } 320 321 /** 322 * Retargets an event to a new source. This method is typically used to 323 * retarget an event to a lightweight child Component of the original 324 * heavyweight source. 325 * <p> 326 * This method is intended to be used only by event targeting subsystems, 327 * such as client-defined KeyboardFocusManagers. It is not for general 328 * client use. 329 * 330 * @param newSource the new Object to which the event should be dispatched 331 * @since 1.4 332 */ 333 public void setSource(Object newSource) { 334 if (source == newSource) { 335 return; 336 } 337 338 Component comp = null; 339 if (newSource instanceof Component) { 340 comp = (Component)newSource; 341 while (comp != null && comp.peer != null && 342 (comp.peer instanceof LightweightPeer)) { 343 comp = comp.parent; 344 } 345 } 346 347 synchronized (this) { 348 source = newSource; 349 if (comp != null) { 350 ComponentPeer peer = comp.peer; 351 if (peer != null) { 352 nativeSetSource(peer); 353 } 354 } 355 } 356 } 357 358 private native void nativeSetSource(ComponentPeer peer); 359 360 /** 361 * Returns the event type. 362 * 363 * @return the event's type id 364 */ 365 public int getID() { 366 return id; 367 } 368 369 /** 370 * Returns a String representation of this object. 371 */ 372 public String toString() { 373 String srcName = null; 374 if (source instanceof Component) { 375 srcName = ((Component)source).getName(); 376 } else if (source instanceof MenuComponent) { 377 srcName = ((MenuComponent)source).getName(); 378 } 379 return getClass().getName() + "[" + paramString() + "] on " + 380 (srcName != null? srcName : source); 381 } 382 383 /** 384 * Returns a string representing the state of this {@code Event}. 385 * This method is intended to be used only for debugging purposes, and the 386 * content and format of the returned string may vary between 387 * implementations. The returned string may be empty but may not be 388 * {@code null}. 389 * 390 * @return a string representation of this event 391 */ 392 public String paramString() { 393 return ""; 394 } 395 396 /** 397 * Consumes this event, if this event can be consumed. Only low-level, 398 * system events can be consumed 399 */ 400 protected void consume() { 401 switch(id) { 402 case KeyEvent.KEY_PRESSED: 403 case KeyEvent.KEY_RELEASED: 404 case MouseEvent.MOUSE_PRESSED: 405 case MouseEvent.MOUSE_RELEASED: 406 case MouseEvent.MOUSE_MOVED: 407 case MouseEvent.MOUSE_DRAGGED: 408 case MouseEvent.MOUSE_ENTERED: 409 case MouseEvent.MOUSE_EXITED: 410 case MouseEvent.MOUSE_WHEEL: 411 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: 412 case InputMethodEvent.CARET_POSITION_CHANGED: 413 consumed = true; 414 break; 415 default: 416 // event type cannot be consumed 417 } 418 } 419 420 /** 421 * Returns whether this event has been consumed. 422 * 423 * @return {@code true} if this event has been consumed; 424 * otherwise {@code false} 425 */ 426 protected boolean isConsumed() { 427 return consumed; 428 } 429 430 /** 431 * Converts a new event to an old one (used for compatibility). 432 * If the new event cannot be converted (because no old equivalent 433 * exists) then this returns null. 434 * 435 * Note: this method is here instead of in each individual new 436 * event class in java.awt.event because we don't want to make 437 * it public and it needs to be called from java.awt. 438 */ 439 Event convertToOld() { 440 Object src = getSource(); 441 int newid = id; 442 443 switch(id) { 444 case KeyEvent.KEY_PRESSED: 445 case KeyEvent.KEY_RELEASED: 446 KeyEvent ke = (KeyEvent)this; 447 if (ke.isActionKey()) { 448 newid = (id == KeyEvent.KEY_PRESSED? 449 Event.KEY_ACTION : Event.KEY_ACTION_RELEASE); 450 } 451 int keyCode = ke.getKeyCode(); 452 if (keyCode == KeyEvent.VK_SHIFT || 453 keyCode == KeyEvent.VK_CONTROL || 454 keyCode == KeyEvent.VK_ALT) { 455 return null; // suppress modifier keys in old event model. 456 } 457 // no mask for button1 existed in old Event - strip it out 458 return new Event(src, ke.getWhen(), newid, 0, 0, 459 Event.getOldEventKey(ke), 460 (ke.getModifiers() & ~InputEvent.BUTTON1_MASK)); 461 462 case MouseEvent.MOUSE_PRESSED: 463 case MouseEvent.MOUSE_RELEASED: 464 case MouseEvent.MOUSE_MOVED: 465 case MouseEvent.MOUSE_DRAGGED: 466 case MouseEvent.MOUSE_ENTERED: 467 case MouseEvent.MOUSE_EXITED: 468 MouseEvent me = (MouseEvent)this; 469 // no mask for button1 existed in old Event - strip it out 470 Event olde = new Event(src, me.getWhen(), newid, 471 me.getX(), me.getY(), 0, 472 (me.getModifiers() & ~InputEvent.BUTTON1_MASK)); 473 olde.clickCount = me.getClickCount(); 474 return olde; 475 476 case FocusEvent.FOCUS_GAINED: 477 return new Event(src, Event.GOT_FOCUS, null); 478 479 case FocusEvent.FOCUS_LOST: 480 return new Event(src, Event.LOST_FOCUS, null); 481 482 case WindowEvent.WINDOW_CLOSING: 483 case WindowEvent.WINDOW_ICONIFIED: 484 case WindowEvent.WINDOW_DEICONIFIED: 485 return new Event(src, newid, null); 486 487 case ComponentEvent.COMPONENT_MOVED: 488 if (src instanceof Frame || src instanceof Dialog) { 489 Point p = ((Component)src).getLocation(); 490 return new Event(src, 0, Event.WINDOW_MOVED, p.x, p.y, 0, 0); 491 } 492 break; 493 494 case ActionEvent.ACTION_PERFORMED: 495 ActionEvent ae = (ActionEvent)this; 496 String cmd; 497 if (src instanceof Button) { 498 cmd = ((Button)src).getLabel(); 499 } else if (src instanceof MenuItem) { 500 cmd = ((MenuItem)src).getLabel(); 501 } else { 502 cmd = ae.getActionCommand(); 503 } 504 return new Event(src, 0, newid, 0, 0, 0, ae.getModifiers(), cmd); 505 506 case ItemEvent.ITEM_STATE_CHANGED: 507 ItemEvent ie = (ItemEvent)this; 508 Object arg; 509 if (src instanceof List) { 510 newid = (ie.getStateChange() == ItemEvent.SELECTED? 511 Event.LIST_SELECT : Event.LIST_DESELECT); 512 arg = ie.getItem(); 513 } else { 514 newid = Event.ACTION_EVENT; 515 if (src instanceof Choice) { 516 arg = ie.getItem(); 517 518 } else { // Checkbox 519 arg = Boolean.valueOf(ie.getStateChange() == ItemEvent.SELECTED); 520 } 521 } 522 return new Event(src, newid, arg); 523 524 case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED: 525 AdjustmentEvent aje = (AdjustmentEvent)this; 526 switch(aje.getAdjustmentType()) { 527 case AdjustmentEvent.UNIT_INCREMENT: 528 newid = Event.SCROLL_LINE_DOWN; 529 break; 530 case AdjustmentEvent.UNIT_DECREMENT: 531 newid = Event.SCROLL_LINE_UP; 532 break; 533 case AdjustmentEvent.BLOCK_INCREMENT: 534 newid = Event.SCROLL_PAGE_DOWN; 535 break; 536 case AdjustmentEvent.BLOCK_DECREMENT: 537 newid = Event.SCROLL_PAGE_UP; 538 break; 539 case AdjustmentEvent.TRACK: 540 if (aje.getValueIsAdjusting()) { 541 newid = Event.SCROLL_ABSOLUTE; 542 } 543 else { 544 newid = Event.SCROLL_END; 545 } 546 break; 547 default: 548 return null; 549 } 550 return new Event(src, newid, Integer.valueOf(aje.getValue())); 551 552 default: 553 } 554 return null; 555 } 556 557 /** 558 * Copies all private data from this event into that. 559 * Space is allocated for the copied data that will be 560 * freed when the that is finalized. Upon completion, 561 * this event is not changed. 562 */ 563 void copyPrivateDataInto(AWTEvent that) { 564 that.bdata = this.bdata; 565 // Copy canAccessSystemClipboard value from this into that. 566 if (this instanceof InputEvent && that instanceof InputEvent) { 567 568 AWTAccessor.InputEventAccessor accessor 569 = AWTAccessor.getInputEventAccessor(); 570 571 boolean b = accessor.canAccessSystemClipboard((InputEvent) this); 572 accessor.setCanAccessSystemClipboard((InputEvent) that, b); 573 } 574 that.isSystemGenerated = this.isSystemGenerated; 575 } 576 577 void dispatched() { 578 if (this instanceof InputEvent) { 579 AWTAccessor.getInputEventAccessor(). 580 setCanAccessSystemClipboard((InputEvent) this, false); 581 } 582 } 583 } // class AWTEvent