001 /*
002 * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package java.awt;
027
028 import java.util.EventObject;
029 import java.awt.event.*;
030 import java.awt.peer.ComponentPeer;
031 import java.awt.peer.LightweightPeer;
032 import java.lang.reflect.Field;
033 import java.util.logging.Logger;
034 import java.util.logging.Level;
035
036 /**
037 * The root event class for all AWT events.
038 * This class and its subclasses supercede the original
039 * java.awt.Event class.
040 * Subclasses of this root AWTEvent class defined outside of the
041 * java.awt.event package should define event ID values greater than
042 * the value defined by RESERVED_ID_MAX.
043 * <p>
044 * The event masks defined in this class are needed by Component subclasses
045 * which are using Component.enableEvents() to select for event types not
046 * selected by registered listeners. If a listener is registered on a
047 * component, the appropriate event mask is already set internally by the
048 * component.
049 * <p>
050 * The masks are also used to specify to which types of events an
051 * AWTEventListener should listen. The masks are bitwise-ORed together
052 * and passed to Toolkit.addAWTEventListener.
053 *
054 * @see Component#enableEvents
055 * @see Toolkit#addAWTEventListener
056 *
057 * @see java.awt.event.ActionEvent
058 * @see java.awt.event.AdjustmentEvent
059 * @see java.awt.event.ComponentEvent
060 * @see java.awt.event.ContainerEvent
061 * @see java.awt.event.FocusEvent
062 * @see java.awt.event.InputMethodEvent
063 * @see java.awt.event.InvocationEvent
064 * @see java.awt.event.ItemEvent
065 * @see java.awt.event.HierarchyEvent
066 * @see java.awt.event.KeyEvent
067 * @see java.awt.event.MouseEvent
068 * @see java.awt.event.MouseWheelEvent
069 * @see java.awt.event.PaintEvent
070 * @see java.awt.event.TextEvent
071 * @see java.awt.event.WindowEvent
072 *
073 * @author Carl Quinn
074 * @author Amy Fowler
075 * @version 1.68 06/05/07
076 * @since 1.1
077 */
078 public abstract class AWTEvent extends EventObject {
079 private static final Logger log = Logger
080 .getLogger("java.awt.AWTEvent");
081 private byte bdata[];
082
083 /**
084 * The event's id.
085 * @serial
086 * @see #getID()
087 * @see #AWTEvent
088 */
089 protected int id;
090
091 /**
092 * Controls whether or not the event is sent back down to the peer once the
093 * source has processed it - false means it's sent to the peer; true means
094 * it's not. Semantic events always have a 'true' value since they were
095 * generated by the peer in response to a low-level event.
096 * @serial
097 * @see #consume
098 * @see #isConsumed
099 */
100 protected boolean consumed = false;
101
102 transient boolean focusManagerIsDispatching = false;
103 transient boolean isPosted;
104
105 /**
106 * The event mask for selecting component events.
107 */
108 public final static long COMPONENT_EVENT_MASK = 0x01;
109
110 /**
111 * The event mask for selecting container events.
112 */
113 public final static long CONTAINER_EVENT_MASK = 0x02;
114
115 /**
116 * The event mask for selecting focus events.
117 */
118 public final static long FOCUS_EVENT_MASK = 0x04;
119
120 /**
121 * The event mask for selecting key events.
122 */
123 public final static long KEY_EVENT_MASK = 0x08;
124
125 /**
126 * The event mask for selecting mouse events.
127 */
128 public final static long MOUSE_EVENT_MASK = 0x10;
129
130 /**
131 * The event mask for selecting mouse motion events.
132 */
133 public final static long MOUSE_MOTION_EVENT_MASK = 0x20;
134
135 /**
136 * The event mask for selecting window events.
137 */
138 public final static long WINDOW_EVENT_MASK = 0x40;
139
140 /**
141 * The event mask for selecting action events.
142 */
143 public final static long ACTION_EVENT_MASK = 0x80;
144
145 /**
146 * The event mask for selecting adjustment events.
147 */
148 public final static long ADJUSTMENT_EVENT_MASK = 0x100;
149
150 /**
151 * The event mask for selecting item events.
152 */
153 public final static long ITEM_EVENT_MASK = 0x200;
154
155 /**
156 * The event mask for selecting text events.
157 */
158 public final static long TEXT_EVENT_MASK = 0x400;
159
160 /**
161 * The event mask for selecting input method events.
162 */
163 public final static long INPUT_METHOD_EVENT_MASK = 0x800;
164
165 /**
166 * The pseudo event mask for enabling input methods.
167 * We're using one bit in the eventMask so we don't need
168 * a separate field inputMethodsEnabled.
169 */
170 final static long INPUT_METHODS_ENABLED_MASK = 0x1000;
171
172 /**
173 * The event mask for selecting paint events.
174 */
175 public final static long PAINT_EVENT_MASK = 0x2000;
176
177 /**
178 * The event mask for selecting invocation events.
179 */
180 public final static long INVOCATION_EVENT_MASK = 0x4000;
181
182 /**
183 * The event mask for selecting hierarchy events.
184 */
185 public final static long HIERARCHY_EVENT_MASK = 0x8000;
186
187 /**
188 * The event mask for selecting hierarchy bounds events.
189 */
190 public final static long HIERARCHY_BOUNDS_EVENT_MASK = 0x10000;
191
192 /**
193 * The event mask for selecting mouse wheel events.
194 * @since 1.4
195 */
196 public final static long MOUSE_WHEEL_EVENT_MASK = 0x20000;
197
198 /**
199 * The event mask for selecting window state events.
200 * @since 1.4
201 */
202 public final static long WINDOW_STATE_EVENT_MASK = 0x40000;
203
204 /**
205 * The event mask for selecting window focus events.
206 * @since 1.4
207 */
208 public final static long WINDOW_FOCUS_EVENT_MASK = 0x80000;
209
210 /**
211 * WARNING: there are more mask defined privately. See
212 * SunToolkit.GRAB_EVENT_MASK.
213 */
214
215 /**
216 * The maximum value for reserved AWT event IDs. Programs defining
217 * their own event IDs should use IDs greater than this value.
218 */
219 public final static int RESERVED_ID_MAX = 1999;
220
221 // security stuff
222 private static Field inputEvent_CanAccessSystemClipboard_Field = null;
223
224 /*
225 * JDK 1.1 serialVersionUID
226 */
227 private static final long serialVersionUID = -1825314779160409405L;
228
229 static {
230 /* ensure that the necessary native libraries are loaded */
231 Toolkit.loadLibraries();
232 if (!GraphicsEnvironment.isHeadless()) {
233 initIDs();
234 }
235 }
236
237 private static synchronized Field get_InputEvent_CanAccessSystemClipboard() {
238 if (inputEvent_CanAccessSystemClipboard_Field == null) {
239 inputEvent_CanAccessSystemClipboard_Field = (Field) java.security.AccessController
240 .doPrivileged(new java.security.PrivilegedAction() {
241 public Object run() {
242 Field field = null;
243 try {
244 field = InputEvent.class
245 .getDeclaredField("canAccessSystemClipboard");
246 field.setAccessible(true);
247 return field;
248 } catch (SecurityException e) {
249 if (log.isLoggable(Level.FINE)) {
250 log
251 .log(
252 Level.FINE,
253 "AWTEvent.get_InputEvent_CanAccessSystemClipboard() got SecurityException ",
254 e);
255 }
256 } catch (NoSuchFieldException e) {
257 if (log.isLoggable(Level.FINE)) {
258 log
259 .log(
260 Level.FINE,
261 "AWTEvent.get_InputEvent_CanAccessSystemClipboard() got NoSuchFieldException ",
262 e);
263 }
264 }
265 return null;
266 }
267 });
268 }
269
270 return inputEvent_CanAccessSystemClipboard_Field;
271 }
272
273 /**
274 * Initialize JNI field and method IDs for fields that may be
275 * accessed from C.
276 */
277 private static native void initIDs();
278
279 /**
280 * Constructs an AWTEvent object from the parameters of a 1.0-style event.
281 * @param event the old-style event
282 */
283 public AWTEvent(Event event) {
284 this (event.target, event.id);
285 }
286
287 /**
288 * Constructs an AWTEvent object with the specified source object and type.
289 *
290 * @param source the object where the event originated
291 * @param id the event type
292 */
293 public AWTEvent(Object source, int id) {
294 super (source);
295 this .id = id;
296 switch (id) {
297 case ActionEvent.ACTION_PERFORMED:
298 case ItemEvent.ITEM_STATE_CHANGED:
299 case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
300 case TextEvent.TEXT_VALUE_CHANGED:
301 consumed = true;
302 break;
303 default:
304 }
305 }
306
307 /**
308 * Retargets an event to a new source. This method is typically used to
309 * retarget an event to a lightweight child Component of the original
310 * heavyweight source.
311 * <p>
312 * This method is intended to be used only by event targeting subsystems,
313 * such as client-defined KeyboardFocusManagers. It is not for general
314 * client use.
315 *
316 * @param newSource the new Object to which the event should be dispatched
317 * @since 1.4
318 */
319 public void setSource(Object newSource) {
320 if (source == newSource) {
321 return;
322 }
323
324 Component comp = null;
325 if (newSource instanceof Component) {
326 comp = (Component) newSource;
327 while (comp != null && comp.peer != null
328 && (comp.peer instanceof LightweightPeer)) {
329 comp = comp.parent;
330 }
331 }
332
333 synchronized (this ) {
334 source = newSource;
335 if (comp != null) {
336 ComponentPeer peer = comp.peer;
337 if (peer != null) {
338 nativeSetSource(peer);
339 }
340 }
341 }
342 }
343
344 private native void nativeSetSource(ComponentPeer peer);
345
346 /**
347 * Returns the event type.
348 */
349 public int getID() {
350 return id;
351 }
352
353 /**
354 * Returns a String representation of this object.
355 */
356 public String toString() {
357 String srcName = null;
358 if (source instanceof Component) {
359 srcName = ((Component) source).getName();
360 } else if (source instanceof MenuComponent) {
361 srcName = ((MenuComponent) source).getName();
362 }
363 return getClass().getName() + "[" + paramString() + "] on "
364 + (srcName != null ? srcName : source);
365 }
366
367 /**
368 * Returns a string representing the state of this <code>Event</code>.
369 * This method is intended to be used only for debugging purposes, and the
370 * content and format of the returned string may vary between
371 * implementations. The returned string may be empty but may not be
372 * <code>null</code>.
373 *
374 * @return a string representation of this event
375 */
376 public String paramString() {
377 return "";
378 }
379
380 /**
381 * Consumes this event, if this event can be consumed. Only low-level,
382 * system events can be consumed
383 */
384 protected void consume() {
385 switch (id) {
386 case KeyEvent.KEY_PRESSED:
387 case KeyEvent.KEY_RELEASED:
388 case MouseEvent.MOUSE_PRESSED:
389 case MouseEvent.MOUSE_RELEASED:
390 case MouseEvent.MOUSE_MOVED:
391 case MouseEvent.MOUSE_DRAGGED:
392 case MouseEvent.MOUSE_ENTERED:
393 case MouseEvent.MOUSE_EXITED:
394 case MouseEvent.MOUSE_WHEEL:
395 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
396 case InputMethodEvent.CARET_POSITION_CHANGED:
397 consumed = true;
398 break;
399 default:
400 // event type cannot be consumed
401 }
402 }
403
404 /**
405 * Returns whether this event has been consumed.
406 */
407 protected boolean isConsumed() {
408 return consumed;
409 }
410
411 /**
412 * Converts a new event to an old one (used for compatibility).
413 * If the new event cannot be converted (because no old equivalent
414 * exists) then this returns null.
415 *
416 * Note: this method is here instead of in each individual new
417 * event class in java.awt.event because we don't want to make
418 * it public and it needs to be called from java.awt.
419 */
420 Event convertToOld() {
421 Object src = getSource();
422 int newid = id;
423
424 switch (id) {
425 case KeyEvent.KEY_PRESSED:
426 case KeyEvent.KEY_RELEASED:
427 KeyEvent ke = (KeyEvent) this ;
428 if (ke.isActionKey()) {
429 newid = (id == KeyEvent.KEY_PRESSED ? Event.KEY_ACTION
430 : Event.KEY_ACTION_RELEASE);
431 }
432 int keyCode = ke.getKeyCode();
433 if (keyCode == KeyEvent.VK_SHIFT
434 || keyCode == KeyEvent.VK_CONTROL
435 || keyCode == KeyEvent.VK_ALT) {
436 return null; // suppress modifier keys in old event model.
437 }
438 // no mask for button1 existed in old Event - strip it out
439 return new Event(src, ke.getWhen(), newid, 0, 0, Event
440 .getOldEventKey(ke),
441 (ke.getModifiers() & ~InputEvent.BUTTON1_MASK));
442
443 case MouseEvent.MOUSE_PRESSED:
444 case MouseEvent.MOUSE_RELEASED:
445 case MouseEvent.MOUSE_MOVED:
446 case MouseEvent.MOUSE_DRAGGED:
447 case MouseEvent.MOUSE_ENTERED:
448 case MouseEvent.MOUSE_EXITED:
449 MouseEvent me = (MouseEvent) this ;
450 // no mask for button1 existed in old Event - strip it out
451 Event olde = new Event(src, me.getWhen(), newid, me.getX(),
452 me.getY(), 0,
453 (me.getModifiers() & ~InputEvent.BUTTON1_MASK));
454 olde.clickCount = me.getClickCount();
455 return olde;
456
457 case FocusEvent.FOCUS_GAINED:
458 return new Event(src, Event.GOT_FOCUS, null);
459
460 case FocusEvent.FOCUS_LOST:
461 return new Event(src, Event.LOST_FOCUS, null);
462
463 case WindowEvent.WINDOW_CLOSING:
464 case WindowEvent.WINDOW_ICONIFIED:
465 case WindowEvent.WINDOW_DEICONIFIED:
466 return new Event(src, newid, null);
467
468 case ComponentEvent.COMPONENT_MOVED:
469 if (src instanceof Frame || src instanceof Dialog) {
470 Point p = ((Component) src).getLocation();
471 return new Event(src, 0, Event.WINDOW_MOVED, p.x, p.y,
472 0, 0);
473 }
474 break;
475
476 case ActionEvent.ACTION_PERFORMED:
477 ActionEvent ae = (ActionEvent) this ;
478 String cmd;
479 if (src instanceof Button) {
480 cmd = ((Button) src).getLabel();
481 } else if (src instanceof MenuItem) {
482 cmd = ((MenuItem) src).getLabel();
483 } else {
484 cmd = ae.getActionCommand();
485 }
486 return new Event(src, 0, newid, 0, 0, 0, ae.getModifiers(),
487 cmd);
488
489 case ItemEvent.ITEM_STATE_CHANGED:
490 ItemEvent ie = (ItemEvent) this ;
491 Object arg;
492 if (src instanceof List) {
493 newid = (ie.getStateChange() == ItemEvent.SELECTED ? Event.LIST_SELECT
494 : Event.LIST_DESELECT);
495 arg = ie.getItem();
496 } else {
497 newid = Event.ACTION_EVENT;
498 if (src instanceof Choice) {
499 arg = ie.getItem();
500
501 } else { // Checkbox
502 arg = Boolean
503 .valueOf(ie.getStateChange() == ItemEvent.SELECTED);
504 }
505 }
506 return new Event(src, newid, arg);
507
508 case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
509 AdjustmentEvent aje = (AdjustmentEvent) this ;
510 switch (aje.getAdjustmentType()) {
511 case AdjustmentEvent.UNIT_INCREMENT:
512 newid = Event.SCROLL_LINE_DOWN;
513 break;
514 case AdjustmentEvent.UNIT_DECREMENT:
515 newid = Event.SCROLL_LINE_UP;
516 break;
517 case AdjustmentEvent.BLOCK_INCREMENT:
518 newid = Event.SCROLL_PAGE_DOWN;
519 break;
520 case AdjustmentEvent.BLOCK_DECREMENT:
521 newid = Event.SCROLL_PAGE_UP;
522 break;
523 case AdjustmentEvent.TRACK:
524 if (aje.getValueIsAdjusting()) {
525 newid = Event.SCROLL_ABSOLUTE;
526 } else {
527 newid = Event.SCROLL_END;
528 }
529 break;
530 default:
531 return null;
532 }
533 return new Event(src, newid, Integer
534 .valueOf(aje.getValue()));
535
536 default:
537 }
538 return null;
539 }
540
541 /**
542 * Copies all private data from this event into that.
543 * Space is allocated for the copied data that will be
544 * freed when the that is finalized. Upon completion,
545 * this event is not changed.
546 */
547 void copyPrivateDataInto(AWTEvent that) {
548 that.bdata = this .bdata;
549 // Copy canAccessSystemClipboard value from this into that.
550 if (this instanceof InputEvent && that instanceof InputEvent) {
551 Field field = get_InputEvent_CanAccessSystemClipboard();
552 if (field != null) {
553 try {
554 boolean b = field.getBoolean(this );
555 field.setBoolean(that, b);
556 } catch (IllegalAccessException e) {
557 if (log.isLoggable(Level.FINE)) {
558 log
559 .log(
560 Level.FINE,
561 "AWTEvent.copyPrivateDataInto() got IllegalAccessException ",
562 e);
563 }
564 }
565 }
566 }
567 }
568
569 void dispatched() {
570 if (this instanceof InputEvent) {
571 Field field = get_InputEvent_CanAccessSystemClipboard();
572 if (field != null) {
573 try {
574 field.setBoolean(this , false);
575 } catch (IllegalAccessException e) {
576 if (log.isLoggable(Level.FINE)) {
577 log
578 .log(
579 Level.FINE,
580 "AWTEvent.dispatched() got IllegalAccessException ",
581 e);
582 }
583 }
584 }
585 }
586 }
587 } // class AWTEvent
|