1. /*
  2. * @(#)MouseEvent.java 1.49 03/12/19
  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.event;
  8. import java.awt.Component;
  9. import java.awt.Event;
  10. import java.awt.GraphicsEnvironment;
  11. import java.awt.Point;
  12. import java.awt.Toolkit;
  13. import java.io.IOException;
  14. import java.io.ObjectInputStream;
  15. /**
  16. * An event which indicates that a mouse action occurred in a component.
  17. * A mouse action is considered to occur in a particular component if and only
  18. * if the mouse cursor is over the unobscured part of the component's bounds
  19. * when the action happens.
  20. * Component bounds can be obscurred by the visible component's children or by a
  21. * menu or by a top-level window.
  22. * This event is used both for mouse events (click, enter, exit) and mouse
  23. * motion events (moves and drags).
  24. * <P>
  25. * This low-level event is generated by a component object for:
  26. * <ul>
  27. * <li>Mouse Events
  28. * <ul>
  29. * <li>a mouse button is pressed
  30. * <li>a mouse button is released
  31. * <li>a mouse button is clicked (pressed and released)
  32. * <li>the mouse cursor enters the unobscured part of component's geometry
  33. * <li>the mouse cursor exits the unobscured part of component's geometry
  34. * </ul>
  35. * <li> Mouse Motion Events
  36. * <ul>
  37. * <li>the mouse is moved
  38. * <li>the mouse is dragged
  39. * </ul>
  40. * </ul>
  41. * <P>
  42. * A <code>MouseEvent</code> object is passed to every
  43. * <code>MouseListener</code>
  44. * or <code>MouseAdapter</code> object which is registered to receive
  45. * the "interesting" mouse events using the component's
  46. * <code>addMouseListener</code> method.
  47. * (<code>MouseAdapter</code> objects implement the
  48. * <code>MouseListener</code> interface.) Each such listener object
  49. * gets a <code>MouseEvent</code> containing the mouse event.
  50. * <P>
  51. * A <code>MouseEvent</code> object is also passed to every
  52. * <code>MouseMotionListener</code> or
  53. * <code>MouseMotionAdapter</code> object which is registered to receive
  54. * mouse motion events using the component's
  55. * <code>addMouseMotionListener</code>
  56. * method. (<code>MouseMotionAdapter</code> objects implement the
  57. * <code>MouseMotionListener</code> interface.) Each such listener object
  58. * gets a <code>MouseEvent</code> containing the mouse motion event.
  59. * <P>
  60. * When a mouse button is clicked, events are generated and sent to the
  61. * registered <code>MouseListener</code>s.
  62. * The state of modal keys can be retrieved using {@link InputEvent#getModifiers}
  63. * and {@link InputEvent#getModifiersEx}.
  64. * The button mask returned by {@link InputEvent#getModifiers} reflects
  65. * only the button that changed state, not the current state of all buttons.
  66. * (Note: Due to overlap in the values of ALT_MASK/BUTTON2_MASK and
  67. * META_MASK/BUTTON3_MASK, this is not always true for mouse events involving
  68. * modifier keys).
  69. * To get the state of all buttons and modifier keys, use
  70. * {@link InputEvent#getModifiersEx}.
  71. * The button which has changed state is returned by {@link MouseEvent#getButton}
  72. * <P>
  73. * For example, if the first mouse button is pressed, events are sent in the
  74. * following order:
  75. * <PRE>
  76. * <b >id </b > <b >modifiers </b > <b >button </b >
  77. * <code>MOUSE_PRESSED</code>: <code>BUTTON1_MASK</code> <code>BUTTON1</code>
  78. * <code>MOUSE_RELEASED</code>: <code>BUTTON1_MASK</code> <code>BUTTON1</code>
  79. * <code>MOUSE_CLICKED</code>: <code>BUTTON1_MASK</code> <code>BUTTON1</code>
  80. * </PRE>
  81. * When multiple mouse buttons are pressed, each press, release, and click
  82. * results in a separate event.
  83. * <P>
  84. * For example, if the user presses <b>button 1</b> followed by
  85. * <b>button 2</b>, and then releases them in the same order,
  86. * the following sequence of events is generated:
  87. * <PRE>
  88. * <b >id </b > <b >modifiers </b > <b >button </b >
  89. * <code>MOUSE_PRESSED</code>: <code>BUTTON1_MASK</code> <code>BUTTON1</code>
  90. * <code>MOUSE_PRESSED</code>: <code>BUTTON2_MASK</code> <code>BUTTON2</code>
  91. * <code>MOUSE_RELEASED</code>: <code>BUTTON1_MASK</code> <code>BUTTON1</code>
  92. * <code>MOUSE_CLICKED</code>: <code>BUTTON1_MASK</code> <code>BUTTON1</code>
  93. * <code>MOUSE_RELEASED</code>: <code>BUTTON2_MASK</code> <code>BUTTON2</code>
  94. * <code>MOUSE_CLICKED</code>: <code>BUTTON2_MASK</code> <code>BUTTON2</code>
  95. * </PRE>
  96. * If <b>button 2</b> is released first, the
  97. * <code>MOUSE_RELEASED</code>/<code>MOUSE_CLICKED</code> pair
  98. * for <code>BUTTON2_MASK</code> arrives first,
  99. * followed by the pair for <code>BUTTON1_MASK</code>.
  100. * <p>
  101. *
  102. * <code>MOUSE_DRAGGED</code> events are delivered to the <code>Component</code>
  103. * in which the mouse button was pressed until the mouse button is released
  104. * (regardless of whether the mouse position is within the bounds of the
  105. * <code>Component</code>). Due to platform-dependent Drag&Drop implementations,
  106. * <code>MOUSE_DRAGGED</code> events may not be delivered during a native
  107. * Drag&Drop operation.
  108. *
  109. * In a multi-screen environment mouse drag events are delivered to the
  110. * <code>Component</code> even if the mouse position is outside the bounds of the
  111. * <code>GraphicsConfiguration</code> associated with that
  112. * <code>Component</code>. However, the reported position for mouse drag events
  113. * in this case may differ from the actual mouse position:
  114. * <ul>
  115. * <li>In a multi-screen environment without a virtual device:
  116. * <br>
  117. * The reported coordinates for mouse drag events are clipped to fit within the
  118. * bounds of the <code>GraphicsConfiguration</code> associated with
  119. * the <code>Component</code>.
  120. * <li>In a multi-screen environment with a virtual device:
  121. * <br>
  122. * The reported coordinates for mouse drag events are clipped to fit within the
  123. * bounds of the virtual device associated with the <code>Component</code>.
  124. * </ul>
  125. *
  126. * @author Carl Quinn
  127. * 1.49, 12/19/03
  128. *
  129. * @see MouseAdapter
  130. * @see MouseListener
  131. * @see MouseMotionAdapter
  132. * @see MouseMotionListener
  133. * @see MouseWheelListener
  134. * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/mouselistener.html">Tutorial: Writing a Mouse Listener</a>
  135. * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/mousemotionlistener.html">Tutorial: Writing a Mouse Motion Listener</a>
  136. * @see <a href="http://www.awl.com/cp/javaseries/jcl1_2.html">Reference: The Java Class Libraries (update file)</a>
  137. *
  138. * @since 1.1
  139. */
  140. public class MouseEvent extends InputEvent {
  141. /**
  142. * The first number in the range of ids used for mouse events.
  143. */
  144. public static final int MOUSE_FIRST = 500;
  145. /**
  146. * The last number in the range of ids used for mouse events.
  147. */
  148. public static final int MOUSE_LAST = 507;
  149. /**
  150. * The "mouse clicked" event. This <code>MouseEvent</code>
  151. * occurs when a mouse button is pressed and released.
  152. */
  153. public static final int MOUSE_CLICKED = MOUSE_FIRST;
  154. /**
  155. * The "mouse pressed" event. This <code>MouseEvent</code>
  156. * occurs when a mouse button is pushed down.
  157. */
  158. public static final int MOUSE_PRESSED = 1 + MOUSE_FIRST; //Event.MOUSE_DOWN
  159. /**
  160. * The "mouse released" event. This <code>MouseEvent</code>
  161. * occurs when a mouse button is let up.
  162. */
  163. public static final int MOUSE_RELEASED = 2 + MOUSE_FIRST; //Event.MOUSE_UP
  164. /**
  165. * The "mouse moved" event. This <code>MouseEvent</code>
  166. * occurs when the mouse position changes.
  167. */
  168. public static final int MOUSE_MOVED = 3 + MOUSE_FIRST; //Event.MOUSE_MOVE
  169. /**
  170. * The "mouse entered" event. This <code>MouseEvent</code>
  171. * occurs when the mouse cursor enters the unobscured part of component's
  172. * geometry.
  173. */
  174. public static final int MOUSE_ENTERED = 4 + MOUSE_FIRST; //Event.MOUSE_ENTER
  175. /**
  176. * The "mouse exited" event. This <code>MouseEvent</code>
  177. * occurs when the mouse cursor exits the unobscured part of component's
  178. * geometry.
  179. */
  180. public static final int MOUSE_EXITED = 5 + MOUSE_FIRST; //Event.MOUSE_EXIT
  181. /**
  182. * The "mouse dragged" event. This <code>MouseEvent</code>
  183. * occurs when the mouse position changes while a mouse button is pressed.
  184. */
  185. public static final int MOUSE_DRAGGED = 6 + MOUSE_FIRST; //Event.MOUSE_DRAG
  186. /**
  187. * The "mouse wheel" event. This is the only <code>MouseWheelEvent</code>.
  188. * It occurs when a mouse equipped with a wheel has its wheel rotated.
  189. * @since 1.4
  190. */
  191. public static final int MOUSE_WHEEL = 7 + MOUSE_FIRST;
  192. /**
  193. * Indicates no mouse buttons; used by {@link #getButton}.
  194. * @since 1.4
  195. */
  196. public static final int NOBUTTON = 0;
  197. /**
  198. * Indicates mouse button #1; used by {@link #getButton}.
  199. * @since 1.4
  200. */
  201. public static final int BUTTON1 = 1;
  202. /**
  203. * Indicates mouse button #2; used by {@link #getButton}.
  204. * @since 1.4
  205. */
  206. public static final int BUTTON2 = 2;
  207. /**
  208. * Indicates mouse button #3; used by {@link #getButton}.
  209. * @since 1.4
  210. */
  211. public static final int BUTTON3 = 3;
  212. /**
  213. * The mouse event's x coordinate.
  214. * The x value is relative to the component that fired the event.
  215. *
  216. * @serial
  217. * @see #getX()
  218. */
  219. int x;
  220. /**
  221. * The mouse event's y coordinate.
  222. * The y value is relative to the component that fired the event.
  223. *
  224. * @serial
  225. * @see #getY()
  226. */
  227. int y;
  228. /**
  229. * Indicates the number of quick consecutive clicks of
  230. * a mouse button.
  231. * clickCount will be valid for only three mouse events :<BR>
  232. * <code>MOUSE_CLICKED</code>,
  233. * <code>MOUSE_PRESSED</code> and
  234. * <code>MOUSE_RELEASED</code>.
  235. * For the above, the <code>clickCount</code> will be at least 1.
  236. * For all other events the count will be 0.
  237. *
  238. * @serial
  239. * @see #getClickCount().
  240. */
  241. int clickCount;
  242. /**
  243. * Indicates which, if any, of the mouse buttons has changed state.
  244. *
  245. * The only legal values are the following constants:
  246. * <code>NOBUTTON</code>,
  247. * <code>BUTTON1</code>,
  248. * <code>BUTTON2</code> or
  249. * <code>BUTTON3</code>.
  250. * @serial
  251. * @see #getButton().
  252. */
  253. int button;
  254. /**
  255. * A property used to indicate whether a Popup Menu
  256. * should appear with a certain gestures.
  257. * If <code>popupTrigger</code> = <code>false</code>,
  258. * no popup menu should appear. If it is <code>true</code>
  259. * then a popup menu should appear.
  260. *
  261. * @serial
  262. * @see java.awt.PopupMenu
  263. * @see #isPopupTrigger()
  264. */
  265. boolean popupTrigger = false;
  266. /*
  267. * JDK 1.1 serialVersionUID
  268. */
  269. private static final long serialVersionUID = -991214153494842848L;
  270. static {
  271. /* ensure that the necessary native libraries are loaded */
  272. NativeLibLoader.loadLibraries();
  273. if (!GraphicsEnvironment.isHeadless()) {
  274. initIDs();
  275. }
  276. }
  277. /**
  278. * Initialize JNI field and method IDs for fields that may be
  279. accessed from C.
  280. */
  281. private static native void initIDs();
  282. /**
  283. * Constructs a <code>MouseEvent</code> object with the
  284. * specified source component,
  285. * type, modifiers, coordinates, and click count.
  286. * <p>
  287. * Note that passing in an invalid <code>id</code> results in
  288. * unspecified behavior. Creating an invalid event (such
  289. * as by using more than one of the old _MASKs, or modifier/button
  290. * values which don't match) results in unspecified behavior.
  291. * This method throws an
  292. * <code>IllegalArgumentException</code> if <code>source</code>
  293. * is <code>null</code>.
  294. *
  295. * @param source the <code>Component</code> that originated the event
  296. * @param id the integer that identifies the event
  297. * @param when a long int that gives the time the event occurred
  298. * @param modifiers the modifier keys down during event (e.g. shift, ctrl,
  299. * alt, meta)
  300. * Either extended _DOWN_MASK or old _MASK modifiers
  301. * should be used, but both models should not be mixed
  302. * in one event. Use of the extended modifiers is
  303. * preferred.
  304. * @param x the horizontal x coordinate for the mouse location
  305. * @param y the vertical y coordinate for the mouse location
  306. * @param clickCount the number of mouse clicks associated with event
  307. * @param popupTrigger a boolean, true if this event is a trigger for a
  308. * popup menu
  309. * @param button which of the mouse buttons has changed state.
  310. * <code>NOBUTTON</code>,
  311. * <code>BUTTON1</code>,
  312. * <code>BUTTON2</code> or
  313. * <code>BUTTON3</code>.
  314. * @throws IllegalArgumentException if an invalid <code>button</code>
  315. * value is passed in
  316. * @throws IllegalArgumentException if <code>source</code> is null
  317. * @since 1.4
  318. */
  319. public MouseEvent(Component source, int id, long when, int modifiers,
  320. int x, int y, int clickCount, boolean popupTrigger,
  321. int button)
  322. {
  323. super(source, id, when, modifiers);
  324. this.x = x;
  325. this.y = y;
  326. this.clickCount = clickCount;
  327. this.popupTrigger = popupTrigger;
  328. if (button < NOBUTTON || button >BUTTON3) {
  329. throw new IllegalArgumentException("Invalid button value");
  330. }
  331. this.button = button;
  332. if ((getModifiers() != 0) && (getModifiersEx() == 0)) {
  333. setNewModifiers();
  334. } else if ((getModifiers() == 0) &&
  335. (getModifiersEx() != 0 ||
  336. button != NOBUTTON))
  337. {
  338. setOldModifiers();
  339. }
  340. }
  341. /**
  342. * Constructs a <code>MouseEvent</code> object with the
  343. * specified source component,
  344. * type, modifiers, coordinates, and click count.
  345. * <p>Note that passing in an invalid <code>id</code> results in
  346. * unspecified behavior. This method throws an
  347. * <code>IllegalArgumentException</code> if <code>source</code>
  348. * is <code>null</code>.
  349. *
  350. * @param source the <code>Component</code> that originated the event
  351. * @param id the integer that identifies the event
  352. * @param when a long int that gives the time the event occurred
  353. * @param modifiers the modifier keys down during event (e.g. shift, ctrl,
  354. * alt, meta)
  355. * Either extended _DOWN_MASK or old _MASK modifiers
  356. * should be used, but both models should not be mixed
  357. * in one event. Use of the extended modifiers is
  358. * preferred.
  359. * @param x the horizontal x coordinate for the mouse location
  360. * @param y the vertical y coordinate for the mouse location
  361. * @param clickCount the number of mouse clicks associated with event
  362. * @param popupTrigger a boolean, true if this event is a trigger for a
  363. * popup menu
  364. * @throws IllegalArgumentException if <code>source</code> is null
  365. */
  366. public MouseEvent(Component source, int id, long when, int modifiers,
  367. int x, int y, int clickCount, boolean popupTrigger) {
  368. this(source, id, when, modifiers, x, y, clickCount, popupTrigger, NOBUTTON);
  369. }
  370. /**
  371. * Returns the horizontal x position of the event relative to the
  372. * source component.
  373. *
  374. * @return x an integer indicating horizontal position relative to
  375. * the component
  376. */
  377. public int getX() {
  378. return x;
  379. }
  380. /**
  381. * Returns the vertical y position of the event relative to the
  382. * source component.
  383. *
  384. * @return y an integer indicating vertical position relative to
  385. * the component
  386. */
  387. public int getY() {
  388. return y;
  389. }
  390. /**
  391. * Returns the x,y position of the event relative to the source component.
  392. *
  393. * @return a <code>Point</code> object containing the x and y coordinates
  394. * relative to the source component
  395. *
  396. */
  397. public Point getPoint() {
  398. int x;
  399. int y;
  400. synchronized (this) {
  401. x = this.x;
  402. y = this.y;
  403. }
  404. return new Point(x, y);
  405. }
  406. /**
  407. * Translates the event's coordinates to a new position
  408. * by adding specified <code>x</code> (horizontal) and <code>y</code>
  409. * (vertical) offsets.
  410. *
  411. * @param x the horizontal x value to add to the current x
  412. * coordinate position
  413. * @param y the vertical y value to add to the current y
  414. coordinate position
  415. */
  416. public synchronized void translatePoint(int x, int y) {
  417. this.x += x;
  418. this.y += y;
  419. }
  420. /**
  421. * Returns the number of mouse clicks associated with this event.
  422. *
  423. * @return integer value for the number of clicks
  424. */
  425. public int getClickCount() {
  426. return clickCount;
  427. }
  428. /**
  429. * Returns which, if any, of the mouse buttons has changed state.
  430. *
  431. * @return one of the following constants:
  432. * <code>NOBUTTON</code>,
  433. * <code>BUTTON1</code>,
  434. * <code>BUTTON2</code> or
  435. * <code>BUTTON3</code>.
  436. * @since 1.4
  437. */
  438. public int getButton() {
  439. return button;
  440. }
  441. /**
  442. * Returns whether or not this mouse event is the popup menu
  443. * trigger event for the platform.
  444. * <p><b>Note</b>: Popup menus are triggered differently
  445. * on different systems. Therefore, <code>isPopupTrigger</code>
  446. * should be checked in both <code>mousePressed</code>
  447. * and <code>mouseReleased</code>
  448. * for proper cross-platform functionality.
  449. *
  450. * @return boolean, true if this event is the popup menu trigger
  451. * for this platform
  452. */
  453. public boolean isPopupTrigger() {
  454. return popupTrigger;
  455. }
  456. /**
  457. * Returns a <code>String</code> describing the modifier keys and
  458. * mouse buttons that were down during the event, such as "Shift",
  459. * or "Ctrl+Shift". These strings can be localized by changing
  460. * the <code>awt.properties</code> file.
  461. * <p>
  462. * Note that <code>InputEvent.ALT_MASK</code> and
  463. * <code>InputEvent.BUTTON2_MASK</code> have the same value,
  464. * so the string "Alt" is returned for both modifiers. Likewise,
  465. * <code>InputEvent.META_MASK</code> and
  466. * <code>InputEvent.BUTTON3_MASK</code> have the same value,
  467. * so the string "Meta" is returned for both modifiers.
  468. *
  469. * @param modifiers a modifier mask describing the modifier keys and
  470. * mouse buttons that were down during the event
  471. * @return string a text description of the combination of modifier
  472. * keys and mouse buttons that were down during the event
  473. * @see InputEvent#getModifiersExText(int)
  474. * @since 1.4
  475. */
  476. public static String getMouseModifiersText(int modifiers) {
  477. StringBuffer buf = new StringBuffer();
  478. if ((modifiers & InputEvent.ALT_MASK) != 0) {
  479. buf.append(Toolkit.getProperty("AWT.alt", "Alt"));
  480. buf.append("+");
  481. }
  482. if ((modifiers & InputEvent.META_MASK) != 0) {
  483. buf.append(Toolkit.getProperty("AWT.meta", "Meta"));
  484. buf.append("+");
  485. }
  486. if ((modifiers & InputEvent.CTRL_MASK) != 0) {
  487. buf.append(Toolkit.getProperty("AWT.control", "Ctrl"));
  488. buf.append("+");
  489. }
  490. if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
  491. buf.append(Toolkit.getProperty("AWT.shift", "Shift"));
  492. buf.append("+");
  493. }
  494. if ((modifiers & InputEvent.ALT_GRAPH_MASK) != 0) {
  495. buf.append(Toolkit.getProperty("AWT.altGraph", "Alt Graph"));
  496. buf.append("+");
  497. }
  498. if ((modifiers & InputEvent.BUTTON1_MASK) != 0) {
  499. buf.append(Toolkit.getProperty("AWT.button1", "Button1"));
  500. buf.append("+");
  501. }
  502. if ((modifiers & InputEvent.BUTTON2_MASK) != 0) {
  503. buf.append(Toolkit.getProperty("AWT.button2", "Button2"));
  504. buf.append("+");
  505. }
  506. if ((modifiers & InputEvent.BUTTON3_MASK) != 0) {
  507. buf.append(Toolkit.getProperty("AWT.button3", "Button3"));
  508. buf.append("+");
  509. }
  510. if (buf.length() > 0) {
  511. buf.setLength(buf.length()-1); // remove trailing '+'
  512. }
  513. return buf.toString();
  514. }
  515. /**
  516. * Returns a parameter string identifying this event.
  517. * This method is useful for event-logging and for debugging.
  518. *
  519. * @return a string identifying the event and its attributes
  520. */
  521. public String paramString() {
  522. StringBuffer str = new StringBuffer(80);
  523. switch(id) {
  524. case MOUSE_PRESSED:
  525. str.append("MOUSE_PRESSED");
  526. break;
  527. case MOUSE_RELEASED:
  528. str.append("MOUSE_RELEASED");
  529. break;
  530. case MOUSE_CLICKED:
  531. str.append("MOUSE_CLICKED");
  532. break;
  533. case MOUSE_ENTERED:
  534. str.append("MOUSE_ENTERED");
  535. break;
  536. case MOUSE_EXITED:
  537. str.append("MOUSE_EXITED");
  538. break;
  539. case MOUSE_MOVED:
  540. str.append("MOUSE_MOVED");
  541. break;
  542. case MOUSE_DRAGGED:
  543. str.append("MOUSE_DRAGGED");
  544. break;
  545. case MOUSE_WHEEL:
  546. str.append("MOUSE_WHEEL");
  547. break;
  548. default:
  549. str.append("unknown type");
  550. }
  551. // (x,y) coordinates
  552. str.append(",(").append(x).append(",").append(y).append(")");
  553. str.append(",button=").append(getButton());
  554. if (getModifiers() != 0) {
  555. str.append(",modifiers=").append(getMouseModifiersText(modifiers));
  556. }
  557. if (getModifiersEx() != 0) {
  558. str.append(",extModifiers=").append(getModifiersExText(modifiers));
  559. }
  560. str.append(",clickCount=").append(clickCount);
  561. return str.toString();
  562. }
  563. /**
  564. * Sets new modifiers by the old ones.
  565. * Also sets button.
  566. */
  567. private void setNewModifiers() {
  568. if ((modifiers & BUTTON1_MASK) != 0) {
  569. modifiers |= BUTTON1_DOWN_MASK;
  570. }
  571. if ((modifiers & BUTTON2_MASK) != 0) {
  572. modifiers |= BUTTON2_DOWN_MASK;
  573. }
  574. if ((modifiers & BUTTON3_MASK) != 0) {
  575. modifiers |= BUTTON3_DOWN_MASK;
  576. }
  577. if (id == MOUSE_PRESSED
  578. || id == MOUSE_RELEASED
  579. || id == MOUSE_CLICKED)
  580. {
  581. if ((modifiers & BUTTON1_MASK) != 0) {
  582. button = BUTTON1;
  583. modifiers &= ~BUTTON2_MASK & ~BUTTON3_MASK;
  584. if (id != MOUSE_PRESSED) {
  585. modifiers &= ~BUTTON1_DOWN_MASK;
  586. }
  587. } else if ((modifiers & BUTTON2_MASK) != 0) {
  588. button = BUTTON2;
  589. modifiers &= ~BUTTON1_MASK & ~BUTTON3_MASK;
  590. if (id != MOUSE_PRESSED) {
  591. modifiers &= ~BUTTON2_DOWN_MASK;
  592. }
  593. } else if ((modifiers & BUTTON3_MASK) != 0) {
  594. button = BUTTON3;
  595. modifiers &= ~BUTTON1_MASK & ~BUTTON2_MASK;
  596. if (id != MOUSE_PRESSED) {
  597. modifiers &= ~BUTTON3_DOWN_MASK;
  598. }
  599. }
  600. }
  601. if ((modifiers & InputEvent.ALT_MASK) != 0) {
  602. modifiers |= InputEvent.ALT_DOWN_MASK;
  603. }
  604. if ((modifiers & InputEvent.META_MASK) != 0) {
  605. modifiers |= InputEvent.META_DOWN_MASK;
  606. }
  607. if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
  608. modifiers |= InputEvent.SHIFT_DOWN_MASK;
  609. }
  610. if ((modifiers & InputEvent.CTRL_MASK) != 0) {
  611. modifiers |= InputEvent.CTRL_DOWN_MASK;
  612. }
  613. if ((modifiers & InputEvent.ALT_GRAPH_MASK) != 0) {
  614. modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
  615. }
  616. }
  617. /**
  618. * Sets old modifiers by the new ones.
  619. */
  620. private void setOldModifiers() {
  621. if (id == MOUSE_PRESSED
  622. || id == MOUSE_RELEASED
  623. || id == MOUSE_CLICKED)
  624. {
  625. switch(button) {
  626. case BUTTON1:
  627. modifiers |= BUTTON1_MASK;
  628. break;
  629. case BUTTON2:
  630. modifiers |= BUTTON2_MASK;
  631. break;
  632. case BUTTON3:
  633. modifiers |= BUTTON3_MASK;
  634. break;
  635. }
  636. } else {
  637. if ((modifiers & BUTTON1_DOWN_MASK) != 0) {
  638. modifiers |= BUTTON1_MASK;
  639. }
  640. if ((modifiers & BUTTON2_DOWN_MASK) != 0) {
  641. modifiers |= BUTTON2_MASK;
  642. }
  643. if ((modifiers & BUTTON3_DOWN_MASK) != 0) {
  644. modifiers |= BUTTON3_MASK;
  645. }
  646. }
  647. if ((modifiers & ALT_DOWN_MASK) != 0) {
  648. modifiers |= ALT_MASK;
  649. }
  650. if ((modifiers & META_DOWN_MASK) != 0) {
  651. modifiers |= META_MASK;
  652. }
  653. if ((modifiers & SHIFT_DOWN_MASK) != 0) {
  654. modifiers |= SHIFT_MASK;
  655. }
  656. if ((modifiers & CTRL_DOWN_MASK) != 0) {
  657. modifiers |= CTRL_MASK;
  658. }
  659. if ((modifiers & ALT_GRAPH_DOWN_MASK) != 0) {
  660. modifiers |= ALT_GRAPH_MASK;
  661. }
  662. }
  663. /**
  664. * Sets new modifiers by the old ones.
  665. * @serial
  666. */
  667. private void readObject(ObjectInputStream s)
  668. throws IOException, ClassNotFoundException {
  669. s.defaultReadObject();
  670. if (getModifiers() != 0 && getModifiersEx() == 0) {
  671. setNewModifiers();
  672. }
  673. }
  674. }