1. /*
  2. * @(#)AWTEvent.java 1.55 04/06/02
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.awt;
  8. import java.util.EventObject;
  9. import java.awt.event.*;
  10. import java.awt.peer.ComponentPeer;
  11. import java.awt.peer.LightweightPeer;
  12. import java.lang.reflect.Field;
  13. /**
  14. * The root event class for all AWT events.
  15. * This class and its subclasses supercede the original
  16. * java.awt.Event class.
  17. * Subclasses of this root AWTEvent class defined outside of the
  18. * java.awt.event package should define event ID values greater than
  19. * the value defined by RESERVED_ID_MAX.
  20. * <p>
  21. * The event masks defined in this class are needed by Component subclasses
  22. * which are using Component.enableEvents() to select for event types not
  23. * selected by registered listeners. If a listener is registered on a
  24. * component, the appropriate event mask is already set internally by the
  25. * component.
  26. * <p>
  27. * The masks are also used to specify to which types of events an
  28. * AWTEventListener should listen. The masks are bitwise-ORed together
  29. * and passed to Toolkit.addAWTEventListener.
  30. *
  31. * @see Component#enableEvents
  32. * @see Toolkit#addAWTEventListener
  33. *
  34. * @see java.awt.event.ActionEvent
  35. * @see java.awt.event.AdjustmentEvent
  36. * @see java.awt.event.ComponentEvent
  37. * @see java.awt.event.ContainerEvent
  38. * @see java.awt.event.FocusEvent
  39. * @see java.awt.event.InputMethodEvent
  40. * @see java.awt.event.InvocationEvent
  41. * @see java.awt.event.ItemEvent
  42. * @see java.awt.event.HierarchyEvent
  43. * @see java.awt.event.KeyEvent
  44. * @see java.awt.event.MouseEvent
  45. * @see java.awt.event.MouseWheelEvent
  46. * @see java.awt.event.PaintEvent
  47. * @see java.awt.event.TextEvent
  48. * @see java.awt.event.WindowEvent
  49. *
  50. * @author Carl Quinn
  51. * @author Amy Fowler
  52. * @version 1.55 06/02/04
  53. * @since 1.1
  54. */
  55. public abstract class AWTEvent extends EventObject {
  56. private byte bdata[];
  57. /**
  58. * The event's id.
  59. * @serial
  60. * @see #getID()
  61. * @see #AWTEvent
  62. */
  63. protected int id;
  64. /**
  65. * Controls whether or not the event is sent back down to the peer once the
  66. * source has processed it - false means it's sent to the peer; true means
  67. * it's not. Semantic events always have a 'true' value since they were
  68. * generated by the peer in response to a low-level event.
  69. * @serial
  70. * @see #consume
  71. * @see #isConsumed
  72. */
  73. protected boolean consumed = false;
  74. transient boolean focusManagerIsDispatching = false;
  75. transient boolean isPosted;
  76. /**
  77. * The event mask for selecting component events.
  78. */
  79. public final static long COMPONENT_EVENT_MASK = 0x01;
  80. /**
  81. * The event mask for selecting container events.
  82. */
  83. public final static long CONTAINER_EVENT_MASK = 0x02;
  84. /**
  85. * The event mask for selecting focus events.
  86. */
  87. public final static long FOCUS_EVENT_MASK = 0x04;
  88. /**
  89. * The event mask for selecting key events.
  90. */
  91. public final static long KEY_EVENT_MASK = 0x08;
  92. /**
  93. * The event mask for selecting mouse events.
  94. */
  95. public final static long MOUSE_EVENT_MASK = 0x10;
  96. /**
  97. * The event mask for selecting mouse motion events.
  98. */
  99. public final static long MOUSE_MOTION_EVENT_MASK = 0x20;
  100. /**
  101. * The event mask for selecting window events.
  102. */
  103. public final static long WINDOW_EVENT_MASK = 0x40;
  104. /**
  105. * The event mask for selecting action events.
  106. */
  107. public final static long ACTION_EVENT_MASK = 0x80;
  108. /**
  109. * The event mask for selecting adjustment events.
  110. */
  111. public final static long ADJUSTMENT_EVENT_MASK = 0x100;
  112. /**
  113. * The event mask for selecting item events.
  114. */
  115. public final static long ITEM_EVENT_MASK = 0x200;
  116. /**
  117. * The event mask for selecting text events.
  118. */
  119. public final static long TEXT_EVENT_MASK = 0x400;
  120. /**
  121. * The event mask for selecting input method events.
  122. */
  123. public final static long INPUT_METHOD_EVENT_MASK = 0x800;
  124. /**
  125. * The pseudo event mask for enabling input methods.
  126. * We're using one bit in the eventMask so we don't need
  127. * a separate field inputMethodsEnabled.
  128. */
  129. final static long INPUT_METHODS_ENABLED_MASK = 0x1000;
  130. /**
  131. * The event mask for selecting paint events.
  132. */
  133. public final static long PAINT_EVENT_MASK = 0x2000;
  134. /**
  135. * The event mask for selecting invocation events.
  136. */
  137. public final static long INVOCATION_EVENT_MASK = 0x4000;
  138. /**
  139. * The event mask for selecting hierarchy events.
  140. */
  141. public final static long HIERARCHY_EVENT_MASK = 0x8000;
  142. /**
  143. * The event mask for selecting hierarchy bounds events.
  144. */
  145. public final static long HIERARCHY_BOUNDS_EVENT_MASK = 0x10000;
  146. /**
  147. * The event mask for selecting mouse wheel events.
  148. * @since 1.4
  149. */
  150. public final static long MOUSE_WHEEL_EVENT_MASK = 0x20000;
  151. /**
  152. * The event mask for selecting window state events.
  153. * @since 1.4
  154. */
  155. public final static long WINDOW_STATE_EVENT_MASK = 0x40000;
  156. /**
  157. * The event mask for selecting window focus events.
  158. * @since 1.4
  159. */
  160. public final static long WINDOW_FOCUS_EVENT_MASK = 0x80000;
  161. /**
  162. * The maximum value for reserved AWT event IDs. Programs defining
  163. * their own event IDs should use IDs greater than this value.
  164. */
  165. public final static int RESERVED_ID_MAX = 1999;
  166. // security stuff
  167. private static Field inputEvent_CanAccessSystemClipboard_Field = null;
  168. /*
  169. * JDK 1.1 serialVersionUID
  170. */
  171. private static final long serialVersionUID = -1825314779160409405L;
  172. static {
  173. /* ensure that the necessary native libraries are loaded */
  174. Toolkit.loadLibraries();
  175. if (!GraphicsEnvironment.isHeadless()) {
  176. initIDs();
  177. }
  178. }
  179. private static synchronized Field get_InputEvent_CanAccessSystemClipboard() {
  180. if (inputEvent_CanAccessSystemClipboard_Field == null) {
  181. inputEvent_CanAccessSystemClipboard_Field =
  182. (Field)java.security.AccessController.doPrivileged(
  183. new java.security.PrivilegedAction() {
  184. public Object run() {
  185. Field field = null;
  186. try {
  187. field = InputEvent.class.
  188. getDeclaredField("canAccessSystemClipboard");
  189. field.setAccessible(true);
  190. return field;
  191. } catch (SecurityException e) {
  192. } catch (NoSuchFieldException e) {
  193. }
  194. return null;
  195. }
  196. });
  197. }
  198. return inputEvent_CanAccessSystemClipboard_Field;
  199. }
  200. /**
  201. * Initialize JNI field and method IDs for fields that may be
  202. * accessed from C.
  203. */
  204. private static native void initIDs();
  205. /**
  206. * Constructs an AWTEvent object from the parameters of a 1.0-style event.
  207. * @param event the old-style event
  208. */
  209. public AWTEvent(Event event) {
  210. this(event.target, event.id);
  211. }
  212. /**
  213. * Constructs an AWTEvent object with the specified source object and type.
  214. * @param source the object where the event originated
  215. * @id the event type
  216. */
  217. public AWTEvent(Object source, int id) {
  218. super(source);
  219. this.id = id;
  220. switch(id) {
  221. case ActionEvent.ACTION_PERFORMED:
  222. case ItemEvent.ITEM_STATE_CHANGED:
  223. case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
  224. case TextEvent.TEXT_VALUE_CHANGED:
  225. consumed = true;
  226. break;
  227. default:
  228. }
  229. }
  230. /**
  231. * Retargets an event to a new source. This method is typically used to
  232. * retarget an event to a lightweight child Component of the original
  233. * heavyweight source.
  234. * <p>
  235. * This method is intended to be used only by event targeting subsystems,
  236. * such as client-defined KeyboardFocusManagers. It is not for general
  237. * client use.
  238. *
  239. * @param newSource the new Object to which the event should be dispatched
  240. */
  241. public void setSource(Object newSource) {
  242. if (source == newSource) {
  243. return;
  244. }
  245. Component comp = null;
  246. if (newSource instanceof Component) {
  247. comp = (Component)newSource;
  248. while (comp != null && comp.peer != null &&
  249. (comp.peer instanceof LightweightPeer)) {
  250. comp = comp.parent;
  251. }
  252. }
  253. synchronized (this) {
  254. source = newSource;
  255. if (comp != null) {
  256. ComponentPeer peer = comp.peer;
  257. if (peer != null) {
  258. nativeSetSource(peer);
  259. }
  260. }
  261. }
  262. }
  263. private native void nativeSetSource(ComponentPeer peer);
  264. /**
  265. * Returns the event type.
  266. */
  267. public int getID() {
  268. return id;
  269. }
  270. /**
  271. * Returns a String representation of this object.
  272. */
  273. public String toString() {
  274. String srcName = null;
  275. if (source instanceof Component) {
  276. srcName = ((Component)source).getName();
  277. } else if (source instanceof MenuComponent) {
  278. srcName = ((MenuComponent)source).getName();
  279. }
  280. return getClass().getName() + "[" + paramString() + "] on " +
  281. (srcName != null? srcName : source);
  282. }
  283. /**
  284. * Returns a string representing the state of this <code>Event</code>.
  285. * This method is intended to be used only for debugging purposes, and the
  286. * content and format of the returned string may vary between
  287. * implementations. The returned string may be empty but may not be
  288. * <code>null</code>.
  289. *
  290. * @return a string representation of this event
  291. */
  292. public String paramString() {
  293. return "";
  294. }
  295. /**
  296. * Consumes this event, if this event can be consumed. Only low-level,
  297. * system events can be consumed
  298. */
  299. protected void consume() {
  300. switch(id) {
  301. case KeyEvent.KEY_PRESSED:
  302. case KeyEvent.KEY_RELEASED:
  303. case MouseEvent.MOUSE_PRESSED:
  304. case MouseEvent.MOUSE_RELEASED:
  305. case MouseEvent.MOUSE_MOVED:
  306. case MouseEvent.MOUSE_DRAGGED:
  307. case MouseEvent.MOUSE_ENTERED:
  308. case MouseEvent.MOUSE_EXITED:
  309. case MouseEvent.MOUSE_WHEEL:
  310. case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
  311. case InputMethodEvent.CARET_POSITION_CHANGED:
  312. consumed = true;
  313. break;
  314. default:
  315. // event type cannot be consumed
  316. }
  317. }
  318. /**
  319. * Returns whether this event has been consumed.
  320. */
  321. protected boolean isConsumed() {
  322. return consumed;
  323. }
  324. /**
  325. * Converts a new event to an old one (used for compatibility).
  326. * If the new event cannot be converted (because no old equivalent
  327. * exists) then this returns null.
  328. *
  329. * Note: this method is here instead of in each individual new
  330. * event class in java.awt.event because we don't want to make
  331. * it public and it needs to be called from java.awt.
  332. */
  333. Event convertToOld() {
  334. Object src = getSource();
  335. int newid = id;
  336. switch(id) {
  337. case KeyEvent.KEY_PRESSED:
  338. case KeyEvent.KEY_RELEASED:
  339. KeyEvent ke = (KeyEvent)this;
  340. if (ke.isActionKey()) {
  341. newid = (id == KeyEvent.KEY_PRESSED?
  342. Event.KEY_ACTION : Event.KEY_ACTION_RELEASE);
  343. }
  344. int keyCode = ke.getKeyCode();
  345. if (keyCode == KeyEvent.VK_SHIFT ||
  346. keyCode == KeyEvent.VK_CONTROL ||
  347. keyCode == KeyEvent.VK_ALT) {
  348. return null; // suppress modifier keys in old event model.
  349. }
  350. // no mask for button1 existed in old Event - strip it out
  351. return new Event(src, ke.getWhen(), newid, 0, 0,
  352. Event.getOldEventKey(ke),
  353. (ke.getModifiers() & ~InputEvent.BUTTON1_MASK));
  354. case MouseEvent.MOUSE_PRESSED:
  355. case MouseEvent.MOUSE_RELEASED:
  356. case MouseEvent.MOUSE_MOVED:
  357. case MouseEvent.MOUSE_DRAGGED:
  358. case MouseEvent.MOUSE_ENTERED:
  359. case MouseEvent.MOUSE_EXITED:
  360. MouseEvent me = (MouseEvent)this;
  361. // no mask for button1 existed in old Event - strip it out
  362. Event olde = new Event(src, me.getWhen(), newid,
  363. me.getX(), me.getY(), 0,
  364. (me.getModifiers() & ~InputEvent.BUTTON1_MASK));
  365. olde.clickCount = me.getClickCount();
  366. return olde;
  367. case FocusEvent.FOCUS_GAINED:
  368. return new Event(src, Event.GOT_FOCUS, null);
  369. case FocusEvent.FOCUS_LOST:
  370. return new Event(src, Event.LOST_FOCUS, null);
  371. case WindowEvent.WINDOW_CLOSING:
  372. case WindowEvent.WINDOW_ICONIFIED:
  373. case WindowEvent.WINDOW_DEICONIFIED:
  374. return new Event(src, newid, null);
  375. case ComponentEvent.COMPONENT_MOVED:
  376. if (src instanceof Frame || src instanceof Dialog) {
  377. Point p = ((Component)src).getLocation();
  378. return new Event(src, 0, Event.WINDOW_MOVED, p.x, p.y, 0, 0);
  379. }
  380. break;
  381. case ActionEvent.ACTION_PERFORMED:
  382. ActionEvent ae = (ActionEvent)this;
  383. String cmd;
  384. if (src instanceof Button) {
  385. cmd = ((Button)src).getLabel();
  386. } else if (src instanceof MenuItem) {
  387. cmd = ((MenuItem)src).getLabel();
  388. } else {
  389. cmd = ae.getActionCommand();
  390. }
  391. return new Event(src, 0, newid, 0, 0, 0, ae.getModifiers(), cmd);
  392. case ItemEvent.ITEM_STATE_CHANGED:
  393. ItemEvent ie = (ItemEvent)this;
  394. Object arg;
  395. if (src instanceof List) {
  396. newid = (ie.getStateChange() == ItemEvent.SELECTED?
  397. Event.LIST_SELECT : Event.LIST_DESELECT);
  398. arg = ie.getItem();
  399. } else {
  400. newid = Event.ACTION_EVENT;
  401. if (src instanceof Choice) {
  402. arg = ie.getItem();
  403. } else { // Checkbox
  404. arg = new Boolean(ie.getStateChange() == ItemEvent.SELECTED);
  405. }
  406. }
  407. return new Event(src, newid, arg);
  408. case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
  409. AdjustmentEvent aje = (AdjustmentEvent)this;
  410. switch(aje.getAdjustmentType()) {
  411. case AdjustmentEvent.UNIT_INCREMENT:
  412. newid = Event.SCROLL_LINE_DOWN;
  413. break;
  414. case AdjustmentEvent.UNIT_DECREMENT:
  415. newid = Event.SCROLL_LINE_UP;
  416. break;
  417. case AdjustmentEvent.BLOCK_INCREMENT:
  418. newid = Event.SCROLL_PAGE_DOWN;
  419. break;
  420. case AdjustmentEvent.BLOCK_DECREMENT:
  421. newid = Event.SCROLL_PAGE_UP;
  422. break;
  423. case AdjustmentEvent.TRACK:
  424. if (aje.getValueIsAdjusting()) {
  425. newid = Event.SCROLL_ABSOLUTE;
  426. }
  427. else {
  428. newid = Event.SCROLL_END;
  429. }
  430. break;
  431. default:
  432. return null;
  433. }
  434. return new Event(src, newid, new Integer(aje.getValue()));
  435. default:
  436. }
  437. return null;
  438. }
  439. /**
  440. * Copies all private data from this event into that.
  441. * Space is allocated for the copied data that will be
  442. * freed when the that is finalized. Upon completion,
  443. * this event is not changed.
  444. */
  445. void copyPrivateDataInto(AWTEvent that) {
  446. that.bdata = this.bdata;
  447. // Copy canAccessSystemClipboard value from this into that.
  448. if (this instanceof InputEvent && that instanceof InputEvent) {
  449. Field field = get_InputEvent_CanAccessSystemClipboard();
  450. if (field != null) {
  451. try {
  452. boolean b = field.getBoolean(this);
  453. field.setBoolean(that, b);
  454. } catch(IllegalAccessException e) {
  455. }
  456. }
  457. }
  458. }
  459. void dispatched() {
  460. if (this instanceof InputEvent) {
  461. Field field = get_InputEvent_CanAccessSystemClipboard();
  462. if (field != null) {
  463. try {
  464. field.setBoolean(this, false);
  465. } catch(IllegalAccessException e) {
  466. }
  467. }
  468. }
  469. }
  470. } // class AWTEvent