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