| /* |
| * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package java.awt; |
| |
| import java.util.EventObject; |
| import java.awt.event.*; |
| import java.awt.peer.ComponentPeer; |
| import java.awt.peer.LightweightPeer; |
| import java.lang.reflect.Field; |
| import sun.awt.AWTAccessor; |
| import sun.util.logging.PlatformLogger; |
| |
| import java.security.AccessControlContext; |
| import java.security.AccessController; |
| |
| /** |
| * The root event class for all AWT events. |
| * This class and its subclasses supersede the original |
| * java.awt.Event class. |
| * Subclasses of this root AWTEvent class defined outside of the |
| * java.awt.event package should define event ID values greater than |
| * the value defined by RESERVED_ID_MAX. |
| * <p> |
| * The event masks defined in this class are needed by Component subclasses |
| * which are using Component.enableEvents() to select for event types not |
| * selected by registered listeners. If a listener is registered on a |
| * component, the appropriate event mask is already set internally by the |
| * component. |
| * <p> |
| * The masks are also used to specify to which types of events an |
| * AWTEventListener should listen. The masks are bitwise-ORed together |
| * and passed to Toolkit.addAWTEventListener. |
| * |
| * @see Component#enableEvents |
| * @see Toolkit#addAWTEventListener |
| * |
| * @see java.awt.event.ActionEvent |
| * @see java.awt.event.AdjustmentEvent |
| * @see java.awt.event.ComponentEvent |
| * @see java.awt.event.ContainerEvent |
| * @see java.awt.event.FocusEvent |
| * @see java.awt.event.InputMethodEvent |
| * @see java.awt.event.InvocationEvent |
| * @see java.awt.event.ItemEvent |
| * @see java.awt.event.HierarchyEvent |
| * @see java.awt.event.KeyEvent |
| * @see java.awt.event.MouseEvent |
| * @see java.awt.event.MouseWheelEvent |
| * @see java.awt.event.PaintEvent |
| * @see java.awt.event.TextEvent |
| * @see java.awt.event.WindowEvent |
| * |
| * @author Carl Quinn |
| * @author Amy Fowler |
| * @since 1.1 |
| */ |
| public abstract class AWTEvent extends EventObject { |
| private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.AWTEvent"); |
| private byte bdata[]; |
| |
| /** |
| * The event's id. |
| * @serial |
| * @see #getID() |
| * @see #AWTEvent |
| */ |
| protected int id; |
| |
| /** |
| * Controls whether or not the event is sent back down to the peer once the |
| * source has processed it - false means it's sent to the peer; true means |
| * it's not. Semantic events always have a 'true' value since they were |
| * generated by the peer in response to a low-level event. |
| * @serial |
| * @see #consume |
| * @see #isConsumed |
| */ |
| protected boolean consumed = false; |
| |
| /* |
| * The event's AccessControlContext. |
| */ |
| private transient volatile AccessControlContext acc = |
| AccessController.getContext(); |
| |
| /* |
| * Returns the acc this event was constructed with. |
| */ |
| final AccessControlContext getAccessControlContext() { |
| if (acc == null) { |
| throw new SecurityException("AWTEvent is missing AccessControlContext"); |
| } |
| return acc; |
| } |
| |
| transient boolean focusManagerIsDispatching = false; |
| transient boolean isPosted; |
| |
| /** |
| * Indicates whether this AWTEvent was generated by the system as |
| * opposed to by user code. |
| */ |
| private transient boolean isSystemGenerated; |
| |
| /** |
| * The event mask for selecting component events. |
| */ |
| public static final long COMPONENT_EVENT_MASK = 0x01; |
| |
| /** |
| * The event mask for selecting container events. |
| */ |
| public static final long CONTAINER_EVENT_MASK = 0x02; |
| |
| /** |
| * The event mask for selecting focus events. |
| */ |
| public static final long FOCUS_EVENT_MASK = 0x04; |
| |
| /** |
| * The event mask for selecting key events. |
| */ |
| public static final long KEY_EVENT_MASK = 0x08; |
| |
| /** |
| * The event mask for selecting mouse events. |
| */ |
| public static final long MOUSE_EVENT_MASK = 0x10; |
| |
| /** |
| * The event mask for selecting mouse motion events. |
| */ |
| public static final long MOUSE_MOTION_EVENT_MASK = 0x20; |
| |
| /** |
| * The event mask for selecting window events. |
| */ |
| public static final long WINDOW_EVENT_MASK = 0x40; |
| |
| /** |
| * The event mask for selecting action events. |
| */ |
| public static final long ACTION_EVENT_MASK = 0x80; |
| |
| /** |
| * The event mask for selecting adjustment events. |
| */ |
| public static final long ADJUSTMENT_EVENT_MASK = 0x100; |
| |
| /** |
| * The event mask for selecting item events. |
| */ |
| public static final long ITEM_EVENT_MASK = 0x200; |
| |
| /** |
| * The event mask for selecting text events. |
| */ |
| public static final long TEXT_EVENT_MASK = 0x400; |
| |
| /** |
| * The event mask for selecting input method events. |
| */ |
| public static final long INPUT_METHOD_EVENT_MASK = 0x800; |
| |
| /** |
| * The pseudo event mask for enabling input methods. |
| * We're using one bit in the eventMask so we don't need |
| * a separate field inputMethodsEnabled. |
| */ |
| static final long INPUT_METHODS_ENABLED_MASK = 0x1000; |
| |
| /** |
| * The event mask for selecting paint events. |
| */ |
| public static final long PAINT_EVENT_MASK = 0x2000; |
| |
| /** |
| * The event mask for selecting invocation events. |
| */ |
| public static final long INVOCATION_EVENT_MASK = 0x4000; |
| |
| /** |
| * The event mask for selecting hierarchy events. |
| */ |
| public static final long HIERARCHY_EVENT_MASK = 0x8000; |
| |
| /** |
| * The event mask for selecting hierarchy bounds events. |
| */ |
| public static final long HIERARCHY_BOUNDS_EVENT_MASK = 0x10000; |
| |
| /** |
| * The event mask for selecting mouse wheel events. |
| * @since 1.4 |
| */ |
| public static final long MOUSE_WHEEL_EVENT_MASK = 0x20000; |
| |
| /** |
| * The event mask for selecting window state events. |
| * @since 1.4 |
| */ |
| public static final long WINDOW_STATE_EVENT_MASK = 0x40000; |
| |
| /** |
| * The event mask for selecting window focus events. |
| * @since 1.4 |
| */ |
| public static final long WINDOW_FOCUS_EVENT_MASK = 0x80000; |
| |
| /** |
| * WARNING: there are more mask defined privately. See |
| * SunToolkit.GRAB_EVENT_MASK. |
| */ |
| |
| /** |
| * The maximum value for reserved AWT event IDs. Programs defining |
| * their own event IDs should use IDs greater than this value. |
| */ |
| public static final int RESERVED_ID_MAX = 1999; |
| |
| // security stuff |
| private static Field inputEvent_CanAccessSystemClipboard_Field = null; |
| |
| /* |
| * JDK 1.1 serialVersionUID |
| */ |
| private static final long serialVersionUID = -1825314779160409405L; |
| |
| static { |
| /* ensure that the necessary native libraries are loaded */ |
| Toolkit.loadLibraries(); |
| if (!GraphicsEnvironment.isHeadless()) { |
| initIDs(); |
| } |
| AWTAccessor.setAWTEventAccessor( |
| new AWTAccessor.AWTEventAccessor() { |
| public void setPosted(AWTEvent ev) { |
| ev.isPosted = true; |
| } |
| |
| public void setSystemGenerated(AWTEvent ev) { |
| ev.isSystemGenerated = true; |
| } |
| |
| public boolean isSystemGenerated(AWTEvent ev) { |
| return ev.isSystemGenerated; |
| } |
| |
| public AccessControlContext getAccessControlContext(AWTEvent ev) { |
| return ev.getAccessControlContext(); |
| } |
| |
| public byte[] getBData(AWTEvent ev) { |
| return ev.bdata; |
| } |
| |
| public void setBData(AWTEvent ev, byte[] bdata) { |
| ev.bdata = bdata; |
| } |
| |
| }); |
| } |
| |
| /** |
| * Initialize JNI field and method IDs for fields that may be |
| * accessed from C. |
| */ |
| private static native void initIDs(); |
| |
| /** |
| * Constructs an AWTEvent object from the parameters of a 1.0-style event. |
| * |
| * @param event the old-style event |
| * @deprecated It is recommended that {@link #AWTEvent(Object, int)} be used |
| * instead |
| */ |
| @Deprecated(since = "9") |
| public AWTEvent(Event event) { |
| this(event.target, event.id); |
| } |
| |
| /** |
| * Constructs an AWTEvent object with the specified source object and type. |
| * |
| * @param source the object where the event originated |
| * @param id the event type |
| */ |
| public AWTEvent(Object source, int id) { |
| super(source); |
| this.id = id; |
| switch(id) { |
| case ActionEvent.ACTION_PERFORMED: |
| case ItemEvent.ITEM_STATE_CHANGED: |
| case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED: |
| case TextEvent.TEXT_VALUE_CHANGED: |
| consumed = true; |
| break; |
| default: |
| } |
| } |
| |
| /** |
| * Retargets an event to a new source. This method is typically used to |
| * retarget an event to a lightweight child Component of the original |
| * heavyweight source. |
| * <p> |
| * This method is intended to be used only by event targeting subsystems, |
| * such as client-defined KeyboardFocusManagers. It is not for general |
| * client use. |
| * |
| * @param newSource the new Object to which the event should be dispatched |
| * @since 1.4 |
| */ |
| public void setSource(Object newSource) { |
| if (source == newSource) { |
| return; |
| } |
| |
| Component comp = null; |
| if (newSource instanceof Component) { |
| comp = (Component)newSource; |
| while (comp != null && comp.peer != null && |
| (comp.peer instanceof LightweightPeer)) { |
| comp = comp.parent; |
| } |
| } |
| |
| synchronized (this) { |
| source = newSource; |
| if (comp != null) { |
| ComponentPeer peer = comp.peer; |
| if (peer != null) { |
| nativeSetSource(peer); |
| } |
| } |
| } |
| } |
| |
| private native void nativeSetSource(ComponentPeer peer); |
| |
| /** |
| * Returns the event type. |
| * |
| * @return the event's type id |
| */ |
| public int getID() { |
| return id; |
| } |
| |
| /** |
| * Returns a String representation of this object. |
| */ |
| public String toString() { |
| String srcName = null; |
| if (source instanceof Component) { |
| srcName = ((Component)source).getName(); |
| } else if (source instanceof MenuComponent) { |
| srcName = ((MenuComponent)source).getName(); |
| } |
| return getClass().getName() + "[" + paramString() + "] on " + |
| (srcName != null? srcName : source); |
| } |
| |
| /** |
| * Returns a string representing the state of this {@code Event}. |
| * This method is intended to be used only for debugging purposes, and the |
| * content and format of the returned string may vary between |
| * implementations. The returned string may be empty but may not be |
| * {@code null}. |
| * |
| * @return a string representation of this event |
| */ |
| public String paramString() { |
| return ""; |
| } |
| |
| /** |
| * Consumes this event, if this event can be consumed. Only low-level, |
| * system events can be consumed |
| */ |
| protected void consume() { |
| switch(id) { |
| case KeyEvent.KEY_PRESSED: |
| case KeyEvent.KEY_RELEASED: |
| case MouseEvent.MOUSE_PRESSED: |
| case MouseEvent.MOUSE_RELEASED: |
| case MouseEvent.MOUSE_MOVED: |
| case MouseEvent.MOUSE_DRAGGED: |
| case MouseEvent.MOUSE_ENTERED: |
| case MouseEvent.MOUSE_EXITED: |
| case MouseEvent.MOUSE_WHEEL: |
| case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: |
| case InputMethodEvent.CARET_POSITION_CHANGED: |
| consumed = true; |
| break; |
| default: |
| // event type cannot be consumed |
| } |
| } |
| |
| /** |
| * Returns whether this event has been consumed. |
| * |
| * @return {@code true} if this event has been consumed; |
| * otherwise {@code false} |
| */ |
| protected boolean isConsumed() { |
| return consumed; |
| } |
| |
| /** |
| * Converts a new event to an old one (used for compatibility). |
| * If the new event cannot be converted (because no old equivalent |
| * exists) then this returns null. |
| * |
| * Note: this method is here instead of in each individual new |
| * event class in java.awt.event because we don't want to make |
| * it public and it needs to be called from java.awt. |
| */ |
| @SuppressWarnings("deprecation") |
| Event convertToOld() { |
| Object src = getSource(); |
| int newid = id; |
| |
| switch(id) { |
| case KeyEvent.KEY_PRESSED: |
| case KeyEvent.KEY_RELEASED: |
| KeyEvent ke = (KeyEvent)this; |
| if (ke.isActionKey()) { |
| newid = (id == KeyEvent.KEY_PRESSED? |
| Event.KEY_ACTION : Event.KEY_ACTION_RELEASE); |
| } |
| int keyCode = ke.getKeyCode(); |
| if (keyCode == KeyEvent.VK_SHIFT || |
| keyCode == KeyEvent.VK_CONTROL || |
| keyCode == KeyEvent.VK_ALT) { |
| return null; // suppress modifier keys in old event model. |
| } |
| // no mask for button1 existed in old Event - strip it out |
| return new Event(src, ke.getWhen(), newid, 0, 0, |
| Event.getOldEventKey(ke), |
| (ke.getModifiers() & ~InputEvent.BUTTON1_MASK)); |
| |
| case MouseEvent.MOUSE_PRESSED: |
| case MouseEvent.MOUSE_RELEASED: |
| case MouseEvent.MOUSE_MOVED: |
| case MouseEvent.MOUSE_DRAGGED: |
| case MouseEvent.MOUSE_ENTERED: |
| case MouseEvent.MOUSE_EXITED: |
| MouseEvent me = (MouseEvent)this; |
| // no mask for button1 existed in old Event - strip it out |
| Event olde = new Event(src, me.getWhen(), newid, |
| me.getX(), me.getY(), 0, |
| (me.getModifiers() & ~InputEvent.BUTTON1_MASK)); |
| olde.clickCount = me.getClickCount(); |
| return olde; |
| |
| case FocusEvent.FOCUS_GAINED: |
| return new Event(src, Event.GOT_FOCUS, null); |
| |
| case FocusEvent.FOCUS_LOST: |
| return new Event(src, Event.LOST_FOCUS, null); |
| |
| case WindowEvent.WINDOW_CLOSING: |
| case WindowEvent.WINDOW_ICONIFIED: |
| case WindowEvent.WINDOW_DEICONIFIED: |
| return new Event(src, newid, null); |
| |
| case ComponentEvent.COMPONENT_MOVED: |
| if (src instanceof Frame || src instanceof Dialog) { |
| Point p = ((Component)src).getLocation(); |
| return new Event(src, 0, Event.WINDOW_MOVED, p.x, p.y, 0, 0); |
| } |
| break; |
| |
| case ActionEvent.ACTION_PERFORMED: |
| ActionEvent ae = (ActionEvent)this; |
| String cmd; |
| if (src instanceof Button) { |
| cmd = ((Button)src).getLabel(); |
| } else if (src instanceof MenuItem) { |
| cmd = ((MenuItem)src).getLabel(); |
| } else { |
| cmd = ae.getActionCommand(); |
| } |
| return new Event(src, 0, newid, 0, 0, 0, ae.getModifiers(), cmd); |
| |
| case ItemEvent.ITEM_STATE_CHANGED: |
| ItemEvent ie = (ItemEvent)this; |
| Object arg; |
| if (src instanceof List) { |
| newid = (ie.getStateChange() == ItemEvent.SELECTED? |
| Event.LIST_SELECT : Event.LIST_DESELECT); |
| arg = ie.getItem(); |
| } else { |
| newid = Event.ACTION_EVENT; |
| if (src instanceof Choice) { |
| arg = ie.getItem(); |
| |
| } else { // Checkbox |
| arg = Boolean.valueOf(ie.getStateChange() == ItemEvent.SELECTED); |
| } |
| } |
| return new Event(src, newid, arg); |
| |
| case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED: |
| AdjustmentEvent aje = (AdjustmentEvent)this; |
| switch(aje.getAdjustmentType()) { |
| case AdjustmentEvent.UNIT_INCREMENT: |
| newid = Event.SCROLL_LINE_DOWN; |
| break; |
| case AdjustmentEvent.UNIT_DECREMENT: |
| newid = Event.SCROLL_LINE_UP; |
| break; |
| case AdjustmentEvent.BLOCK_INCREMENT: |
| newid = Event.SCROLL_PAGE_DOWN; |
| break; |
| case AdjustmentEvent.BLOCK_DECREMENT: |
| newid = Event.SCROLL_PAGE_UP; |
| break; |
| case AdjustmentEvent.TRACK: |
| if (aje.getValueIsAdjusting()) { |
| newid = Event.SCROLL_ABSOLUTE; |
| } |
| else { |
| newid = Event.SCROLL_END; |
| } |
| break; |
| default: |
| return null; |
| } |
| return new Event(src, newid, Integer.valueOf(aje.getValue())); |
| |
| default: |
| } |
| return null; |
| } |
| |
| /** |
| * Copies all private data from this event into that. |
| * Space is allocated for the copied data that will be |
| * freed when the that is finalized. Upon completion, |
| * this event is not changed. |
| */ |
| void copyPrivateDataInto(AWTEvent that) { |
| that.bdata = this.bdata; |
| // Copy canAccessSystemClipboard value from this into that. |
| if (this instanceof InputEvent && that instanceof InputEvent) { |
| |
| AWTAccessor.InputEventAccessor accessor |
| = AWTAccessor.getInputEventAccessor(); |
| |
| boolean b = accessor.canAccessSystemClipboard((InputEvent) this); |
| accessor.setCanAccessSystemClipboard((InputEvent) that, b); |
| } |
| that.isSystemGenerated = this.isSystemGenerated; |
| } |
| |
| void dispatched() { |
| if (this instanceof InputEvent) { |
| AWTAccessor.getInputEventAccessor(). |
| setCanAccessSystemClipboard((InputEvent) this, false); |
| } |
| } |
| } // class AWTEvent |