Source for java.awt.event.MouseEvent

   1: /* MouseEvent.java -- a mouse event
   2:    Copyright (C) 1999, 2002, 2004, 2005  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.awt.event;
  40: 
  41: import gnu.java.awt.EventModifier;
  42: 
  43: import java.awt.Component;
  44: import java.awt.Point;
  45: import java.awt.PopupMenu;
  46: import java.io.IOException;
  47: import java.io.ObjectInputStream;
  48: 
  49: /**
  50:  * This event is generated for a mouse event. There are three main categories
  51:  * of mouse events: Regular events include pressing, releasing, and clicking
  52:  * buttons, as well as moving over the boundary of the unobscured portion of
  53:  * a component. Motion events include movement and dragging. Wheel events are
  54:  * covered separately by the subclass MouseWheelEvent.
  55:  *
  56:  * <p>A mouse event is tied to the unobstructed visible component that the
  57:  * mouse cursor was over at the time of the action. The button that was
  58:  * most recently pressed is the only one that shows up in
  59:  * <code>getModifiers</code>, and is returned by <code>getButton</code>,
  60:  * while all buttons that are down show up in <code>getModifiersEx</code>.
  61:  *
  62:  * <p>Drag events may be cut short if native drag-and-drop operations steal
  63:  * the event. Likewise, if a mouse drag exceeds the bounds of a window or
  64:  * virtual device, some platforms may clip the path to fit in the bounds of
  65:  * the component.
  66:  *
  67:  * @author Aaron M. Renn (arenn@urbanophile.com)
  68:  * @author Eric Blake (ebb9@email.byu.edu)
  69:  * @see MouseAdapter
  70:  * @see MouseListener
  71:  * @see MouseMotionAdapter
  72:  * @see MouseMotionListener
  73:  * @see MouseWheelListener
  74:  * @since 1.1
  75:  * @status updated to 1.4
  76:  */
  77: public class MouseEvent extends InputEvent
  78: {
  79:   /**
  80:    * Compatible with JDK 1.1+.
  81:    */
  82:   private static final long serialVersionUID = -991214153494842848L;
  83: 
  84:   /** This is the first id in the range of event ids used by this class. */
  85:   public static final int MOUSE_FIRST = 500;
  86: 
  87:   /** This is the last id in the range of event ids used by this class. */
  88:   public static final int MOUSE_LAST = 507;
  89: 
  90:   /** This event id indicates that the mouse was clicked. */
  91:   public static final int MOUSE_CLICKED = 500;
  92: 
  93:   /** This event id indicates that the mouse was pressed. */
  94:   public static final int MOUSE_PRESSED = 501;
  95: 
  96:   /** This event id indicates that the mouse was released. */
  97:   public static final int MOUSE_RELEASED = 502;
  98: 
  99:   /** This event id indicates that the mouse was moved. */
 100:   public static final int MOUSE_MOVED = 503;
 101: 
 102:   /** This event id indicates that the mouse entered a component. */
 103:   public static final int MOUSE_ENTERED = 504;
 104: 
 105:   /** This event id indicates that the mouse exited a component. */
 106:   public static final int MOUSE_EXITED = 505;
 107: 
 108:   /**
 109:    * This indicates that no button changed state.
 110:    *
 111:    * @see #getButton()
 112:    * @since 1.4
 113:    */
 114:   public static final int NOBUTTON = 0;
 115: 
 116:   /**
 117:    * This indicates that button 1 changed state.
 118:    *
 119:    * @see #getButton()
 120:    * @since 1.4
 121:    */
 122:   public static final int BUTTON1 = 1;
 123: 
 124:   /**
 125:    * This indicates that button 2 changed state.
 126:    *
 127:    * @see #getButton()
 128:    * @since 1.4
 129:    */
 130:   public static final int BUTTON2 = 2;
 131: 
 132:   /**
 133:    * This indicates that button 3 changed state.
 134:    *
 135:    * @see #getButton()
 136:    * @since 1.4
 137:    */
 138:   public static final int BUTTON3 = 3;
 139: 
 140:   /** This event id indicates that the mouse was dragged over a component. */
 141:   public static final int MOUSE_DRAGGED = 506;
 142: 
 143:   /**
 144:    * This event id indicates that the mouse wheel was rotated.
 145:    *
 146:    * @since 1.4
 147:    */
 148:   public static final int MOUSE_WHEEL = 507;
 149: 
 150:   /**
 151:    * The X coordinate of the mouse cursor at the time of the event.
 152:    *
 153:    * @see #getX()
 154:    * @serial the x coordinate
 155:   */
 156:   private int x;
 157: 
 158:   /**
 159:    * The Y coordinate of the mouse cursor at the time of the event.
 160:    *
 161:    * @see #getY()
 162:    * @serial the y coordinate
 163:    */
 164:   private int y;
 165: 
 166:   /**
 167:    * The screen position of that mouse event, X coordinate.
 168:    */
 169:   private int absX;
 170: 
 171:   /**
 172:    * The screen position of that mouse event, Y coordinate.
 173:    */
 174:   private int absY;
 175: 
 176:   /**
 177:    * The number of clicks that took place. For MOUSE_CLICKED, MOUSE_PRESSED,
 178:    * and MOUSE_RELEASED, this will be at least 1; otherwise it is 0.
 179:    *
 180:    * see #getClickCount()
 181:    * @serial the number of clicks
 182:    */
 183:   private final int clickCount;
 184: 
 185:   /**
 186:    * Indicates which mouse button changed state. Can only be one of
 187:    * {@link #NOBUTTON}, {@link #BUTTON1}, {@link #BUTTON2}, or
 188:    * {@link #BUTTON3}.
 189:    *
 190:    * @see #getButton()
 191:    * @since 1.4
 192:    */
 193:   private int button;
 194: 
 195:   /**
 196:    * Whether or not this event should trigger a popup menu.
 197:    *
 198:    * @see PopupMenu
 199:    * @see #isPopupTrigger()
 200:    * @serial true if this is a popup trigger
 201:    */
 202:   private final boolean popupTrigger;
 203: 
 204:   /**
 205:    * Initializes a new instance of <code>MouseEvent</code> with the specified
 206:    * information. Note that an invalid id leads to unspecified results.
 207:    *
 208:    * @param source the source of the event
 209:    * @param id the event id
 210:    * @param when the timestamp of when the event occurred
 211:    * @param modifiers the modifier keys during the event, in old or new style
 212:    * @param x the X coordinate of the mouse point
 213:    * @param y the Y coordinate of the mouse point
 214:    * @param clickCount the number of mouse clicks for this event
 215:    * @param popupTrigger true if this event triggers a popup menu
 216:    * @param button the most recent mouse button to change state
 217:    * @throws IllegalArgumentException if source is null or button is invalid
 218:    * @since 1.4
 219:    */
 220:   public MouseEvent(Component source, int id, long when, int modifiers,
 221:                     int x, int y, int clickCount, boolean popupTrigger,
 222:                     int button)
 223:   {
 224:     this(source, id, when, modifiers, x, y, 0, 0, clickCount, popupTrigger,
 225:          button);
 226:   }
 227: 
 228:   /**
 229:    * Initializes a new instance of <code>MouseEvent</code> with the specified
 230:    * information. Note that an invalid id leads to unspecified results.
 231:    *
 232:    * @param source the source of the event
 233:    * @param id the event id
 234:    * @param when the timestamp of when the event occurred
 235:    * @param modifiers the modifier keys during the event, in old or new style
 236:    * @param x the X coordinate of the mouse point
 237:    * @param y the Y coordinate of the mouse point
 238:    * @param clickCount the number of mouse clicks for this event
 239:    * @param popupTrigger true if this event triggers a popup menu
 240:    * @throws IllegalArgumentException if source is null
 241:    */
 242:   public MouseEvent(Component source, int id, long when, int modifiers,
 243:                     int x, int y, int clickCount, boolean popupTrigger)
 244:   {
 245:     this(source, id, when, modifiers, x, y, clickCount, popupTrigger,
 246:          NOBUTTON);
 247:   }
 248: 
 249:   /**
 250:    * Creates a new MouseEvent. This is like the other constructors and adds
 251:    * specific absolute coordinates.
 252:    *
 253:    * @param source the source of the event
 254:    * @param id the event id
 255:    * @param when the timestamp of when the event occurred
 256:    * @param modifiers the modifier keys during the event, in old or new style
 257:    * @param x the X coordinate of the mouse point
 258:    * @param y the Y coordinate of the mouse point
 259:    * @param absX the absolute X screen coordinate of this event
 260:    * @param absY the absolute Y screen coordinate of this event
 261:    * @param clickCount the number of mouse clicks for this event
 262:    * @param popupTrigger true if this event triggers a popup menu
 263:    * @param button the most recent mouse button to change state
 264:    *
 265:    * @throws IllegalArgumentException if source is null or button is invalid
 266:    *
 267:    * @since 1.6
 268:    */
 269:   public MouseEvent(Component source, int id, long when, int modifiers,
 270:                     int x, int y, int absX, int absY, int clickCount,
 271:                     boolean popupTrigger, int button)
 272:   {
 273:     super(source, id, when, modifiers);
 274: 
 275:     this.x = x;
 276:     this.y = y;
 277:     this.clickCount = clickCount;
 278:     this.popupTrigger = popupTrigger;
 279:     this.button = button;
 280:     if (button < NOBUTTON || button > BUTTON3)
 281:       throw new IllegalArgumentException();
 282:     if ((modifiers & EventModifier.OLD_MASK) != 0)
 283:       {
 284:         if ((modifiers & BUTTON1_MASK) != 0)
 285:           this.button = BUTTON1;
 286:         else if ((modifiers & BUTTON2_MASK) != 0)
 287:           this.button = BUTTON2;
 288:         else if ((modifiers & BUTTON3_MASK) != 0)
 289:           this.button = BUTTON3;
 290:       }
 291:     // clear the mouse button modifier masks if this is a button
 292:     // release event.
 293:     if (id == MOUSE_RELEASED)
 294:       this.modifiersEx &= ~(BUTTON1_DOWN_MASK
 295:                 | BUTTON2_DOWN_MASK
 296:                 | BUTTON3_DOWN_MASK);
 297: 
 298:     this.absX = absX;
 299:     this.absY = absY;
 300:   }
 301: 
 302:   /**
 303:    * This method returns the X coordinate of the mouse position. This is
 304:    * relative to the source component.
 305:    *
 306:    * @return the x coordinate
 307:    */
 308:   public int getX()
 309:   {
 310:     return x;
 311:   }
 312: 
 313:   /**
 314:    * This method returns the Y coordinate of the mouse position. This is
 315:    * relative to the source component.
 316:    *
 317:    * @return the y coordinate
 318:    */
 319:   public int getY()
 320:   {
 321:     return y;
 322:   }
 323: 
 324:   /**
 325:    * @since 1.6
 326:    */
 327:   public Point getLocationOnScreen()
 328:   {
 329:     return new Point(absX, absY);
 330:   }
 331: 
 332:   /**
 333:    * @since 1.6
 334:    */
 335:   public int getXOnScreen()
 336:   {
 337:     return absX;
 338:   }
 339: 
 340:   /**
 341:    * @since 1.6
 342:    */
 343:   public int getYOnScreen()
 344:   {
 345:     return absY;
 346:   }
 347: 
 348:   /**
 349:    * This method returns a <code>Point</code> for the x,y position of
 350:    * the mouse pointer. This is relative to the source component.
 351:    *
 352:    * @return a <code>Point</code> for the event position
 353:    */
 354:   public Point getPoint()
 355:   {
 356:     return new Point(x, y);
 357:   }
 358: 
 359:   /**
 360:    * Translates the event coordinates by the specified x and y offsets.
 361:    *
 362:    * @param dx the value to add to the X coordinate of this event
 363:    * @param dy the value to add to the Y coordiante of this event
 364:    */
 365:   public void translatePoint(int dx, int dy)
 366:   {
 367:     x += dx;
 368:     y += dy;
 369:   }
 370: 
 371:   /**
 372:    * This method returns the number of mouse clicks associated with this
 373:    * event.
 374:    *
 375:    * @return the number of mouse clicks for this event
 376:    */
 377:   public int getClickCount()
 378:   {
 379:     return clickCount;
 380:   }
 381: 
 382:   /**
 383:    * Returns which button, if any, was the most recent to change state. This
 384:    * will be one of {@link #NOBUTTON}, {@link #BUTTON1}, {@link #BUTTON2}, or
 385:    * {@link #BUTTON3}.
 386:    *
 387:    * @return the button that changed state
 388:    * @since 1.4
 389:    */
 390:   public int getButton()
 391:   {
 392:     return button;
 393:   }
 394: 
 395:   /**
 396:    * This method tests whether or not the event is a popup menu trigger. This
 397:    * should be checked in both MousePressed and MouseReleased to be
 398:    * cross-platform compatible, as different systems have different popup
 399:    * triggers.
 400:    *
 401:    * @return true if the event is a popup menu trigger
 402:    */
 403:   public boolean isPopupTrigger()
 404:   {
 405:     return popupTrigger;
 406:   }
 407: 
 408:   /**
 409:    * Returns a string describing the modifiers, such as "Shift" or
 410:    * "Ctrl+Button1".
 411:    *
 412:    * XXX Sun claims this can be localized via the awt.properties file - how
 413:    * do we implement that?
 414:    *
 415:    * @param modifiers the old-style modifiers to convert to text
 416:    * @return a string representation of the modifiers in this bitmask
 417:    */
 418:   public static String getMouseModifiersText(int modifiers)
 419:   {
 420:     modifiers &= EventModifier.OLD_MASK;
 421:     if ((modifiers & BUTTON2_MASK) != 0)
 422:       modifiers |= BUTTON2_DOWN_MASK;
 423:     if ((modifiers & BUTTON3_MASK) != 0)
 424:       modifiers |= BUTTON3_DOWN_MASK;
 425:     return getModifiersExText(EventModifier.extend(modifiers));
 426:   }
 427: 
 428:   /**
 429:    * Returns a string identifying this event. This is formatted as the field
 430:    * name of the id type, followed by the (x,y) point, the most recent button
 431:    * changed, modifiers (if any), extModifiers (if any), and clickCount.
 432:    *
 433:    * @return a string identifying this event
 434:    */
 435:   public String paramString()
 436:   {
 437:     StringBuffer s = new StringBuffer();
 438:     switch (id)
 439:       {
 440:       case MOUSE_CLICKED:
 441:         s.append("MOUSE_CLICKED,(");
 442:         break;
 443:       case MOUSE_PRESSED:
 444:         s.append("MOUSE_PRESSED,(");
 445:         break;
 446:       case MOUSE_RELEASED:
 447:         s.append("MOUSE_RELEASED,(");
 448:         break;
 449:       case MOUSE_MOVED:
 450:         s.append("MOUSE_MOVED,(");
 451:         break;
 452:       case MOUSE_ENTERED:
 453:         s.append("MOUSE_ENTERED,(");
 454:         break;
 455:       case MOUSE_EXITED:
 456:         s.append("MOUSE_EXITED,(");
 457:         break;
 458:       case MOUSE_DRAGGED:
 459:         s.append("MOUSE_DRAGGED,(");
 460:         break;
 461:       case MOUSE_WHEEL:
 462:         s.append("MOUSE_WHEEL,(");
 463:         break;
 464:       default:
 465:         s.append("unknown type,(");
 466:       }
 467:     s.append(x).append(',').append(y).append("),button=").append(button);
 468:     // FIXME: need a mauve test for this method
 469:     if (modifiersEx != 0)
 470:       s.append(",extModifiers=").append(getModifiersExText(modifiersEx));
 471:     
 472:     s.append(",clickCount=").append(clickCount);
 473:     s.append(",consumed=").append(consumed);
 474:     
 475:     return s.toString();
 476:   }
 477: 
 478:   /**
 479:    * Reads in the object from a serial stream.
 480:    *
 481:    * @param s the stream to read from
 482:    * @throws IOException if deserialization fails
 483:    * @throws ClassNotFoundException if deserialization fails
 484:    * @serialData default, except that the modifiers are converted to new style
 485:    */
 486:   private void readObject(ObjectInputStream s)
 487:     throws IOException, ClassNotFoundException
 488:   {
 489:     s.defaultReadObject();
 490:     if ((modifiers & EventModifier.OLD_MASK) != 0)
 491:       {
 492:         if ((modifiers & BUTTON1_MASK) != 0)
 493:           button = BUTTON1;
 494:         else if ((modifiers & BUTTON2_MASK) != 0)
 495:           button = BUTTON2;
 496:         else if ((modifiers & BUTTON3_MASK) != 0)
 497:           button = BUTTON3;
 498:         modifiersEx = EventModifier.extend(modifiers) & EventModifier.NEW_MASK;
 499:       }
 500:   }
 501: } // class MouseEvent