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
|