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.io.IOException;
  46: import java.io.ObjectInputStream;
  47: 
  48: /**
  49:  * This event is generated for a mouse event. There are three main categories
  50:  * of mouse events: Regular events include pressing, releasing, and clicking
  51:  * buttons, as well as moving over the boundary of the unobscured portion of
  52:  * a component. Motion events include movement and dragging. Wheel events are
  53:  * covered separately by the subclass MouseWheelEvent.
  54:  *
  55:  * <p>A mouse event is tied to the unobstructed visible component that the
  56:  * mouse cursor was over at the time of the action. The button that was
  57:  * most recently pressed is the only one that shows up in
  58:  * <code>getModifiers</code>, and is returned by <code>getButton</code>,
  59:  * while all buttons that are down show up in <code>getModifiersEx</code>.
  60:  *
  61:  * <p>Drag events may be cut short if native drag-and-drop operations steal
  62:  * the event. Likewise, if a mouse drag exceeds the bounds of a window or
  63:  * virtual device, some platforms may clip the path to fit in the bounds of
  64:  * the component.
  65:  *
  66:  * @author Aaron M. Renn (arenn@urbanophile.com)
  67:  * @author Eric Blake (ebb9@email.byu.edu)
  68:  * @see MouseAdapter
  69:  * @see MouseListener
  70:  * @see MouseMotionAdapter
  71:  * @see MouseMotionListener
  72:  * @see MouseWheelListener
  73:  * @since 1.1
  74:  * @status updated to 1.4
  75:  */
  76: public class MouseEvent extends InputEvent
  77: {
  78:   /**
  79:    * Compatible with JDK 1.1+.
  80:    */
  81:   private static final long serialVersionUID = -991214153494842848L;
  82: 
  83:   /** This is the first id in the range of event ids used by this class. */
  84:   public static final int MOUSE_FIRST = 500;
  85: 
  86:   /** This is the last id in the range of event ids used by this class. */
  87:   public static final int MOUSE_LAST = 507;
  88: 
  89:   /** This event id indicates that the mouse was clicked. */
  90:   public static final int MOUSE_CLICKED = 500;
  91: 
  92:   /** This event id indicates that the mouse was pressed. */
  93:   public static final int MOUSE_PRESSED = 501;
  94: 
  95:   /** This event id indicates that the mouse was released. */
  96:   public static final int MOUSE_RELEASED = 502;
  97: 
  98:   /** This event id indicates that the mouse was moved. */
  99:   public static final int MOUSE_MOVED = 503;
 100: 
 101:   /** This event id indicates that the mouse entered a component. */
 102:   public static final int MOUSE_ENTERED = 504;
 103: 
 104:   /** This event id indicates that the mouse exited a component. */
 105:   public static final int MOUSE_EXITED = 505;
 106: 
 107:   /**
 108:    * This indicates that no button changed state.
 109:    *
 110:    * @see #getButton()
 111:    * @since 1.4
 112:    */
 113:   public static final int NOBUTTON = 0;
 114: 
 115:   /**
 116:    * This indicates that button 1 changed state.
 117:    *
 118:    * @see #getButton()
 119:    * @since 1.4
 120:    */
 121:   public static final int BUTTON1 = 1;
 122: 
 123:   /**
 124:    * This indicates that button 2 changed state.
 125:    *
 126:    * @see #getButton()
 127:    * @since 1.4
 128:    */
 129:   public static final int BUTTON2 = 2;
 130: 
 131:   /**
 132:    * This indicates that button 3 changed state.
 133:    *
 134:    * @see #getButton()
 135:    * @since 1.4
 136:    */
 137:   public static final int BUTTON3 = 3;
 138: 
 139:   /** This event id indicates that the mouse was dragged over a component. */
 140:   public static final int MOUSE_DRAGGED = 506;
 141: 
 142:   /**
 143:    * This event id indicates that the mouse wheel was rotated.
 144:    *
 145:    * @since 1.4
 146:    */
 147:   public static final int MOUSE_WHEEL = 507;
 148: 
 149:   /**
 150:    * The X coordinate of the mouse cursor at the time of the event.
 151:    *
 152:    * @see #getX()
 153:    * @serial the x coordinate
 154:   */
 155:   private int x;
 156: 
 157:   /**
 158:    * The Y coordinate of the mouse cursor at the time of the event.
 159:    *
 160:    * @see #getY()
 161:    * @serial the y coordinate
 162:    */
 163:   private int y;
 164: 
 165:   /**
 166:    * The number of clicks that took place. For MOUSE_CLICKED, MOUSE_PRESSED,
 167:    * and MOUSE_RELEASED, this will be at least 1; otherwise it is 0.
 168:    *
 169:    * see #getClickCount()
 170:    * @serial the number of clicks
 171:    */
 172:   private final int clickCount;
 173: 
 174:   /**
 175:    * Indicates which mouse button changed state. Can only be one of
 176:    * {@link #NOBUTTON}, {@link #BUTTON1}, {@link #BUTTON2}, or
 177:    * {@link #BUTTON3}.
 178:    *
 179:    * @see #getButton()
 180:    * @since 1.4
 181:    */
 182:   private int button;
 183: 
 184:   /**
 185:    * Whether or not this event should trigger a popup menu.
 186:    *
 187:    * @see PopupMenu
 188:    * @see #isPopupTrigger()
 189:    * @serial true if this is a popup trigger
 190:    */
 191:   private final boolean popupTrigger;
 192: 
 193:   /**
 194:    * Initializes a new instance of <code>MouseEvent</code> with the specified
 195:    * information. Note that an invalid id leads to unspecified results.
 196:    *
 197:    * @param source the source of the event
 198:    * @param id the event id
 199:    * @param when the timestamp of when the event occurred
 200:    * @param modifiers the modifier keys during the event, in old or new style
 201:    * @param x the X coordinate of the mouse point
 202:    * @param y the Y coordinate of the mouse point
 203:    * @param clickCount the number of mouse clicks for this event
 204:    * @param popupTrigger true if this event triggers a popup menu
 205:    * @param button the most recent mouse button to change state
 206:    * @throws IllegalArgumentException if source is null or button is invalid
 207:    * @since 1.4
 208:    */
 209:   public MouseEvent(Component source, int id, long when, int modifiers,
 210:                     int x, int y, int clickCount, boolean popupTrigger,
 211:                     int button)
 212:   {
 213:     super(source, id, when, modifiers);
 214:     this.x = x;
 215:     this.y = y;
 216:     this.clickCount = clickCount;
 217:     this.popupTrigger = popupTrigger;
 218:     this.button = button;
 219:     if (button < NOBUTTON || button > BUTTON3)
 220:       throw new IllegalArgumentException();
 221:     if ((modifiers & EventModifier.OLD_MASK) != 0)
 222:       {
 223:         if ((modifiers & BUTTON1_MASK) != 0)
 224:           this.button = BUTTON1;
 225:         else if ((modifiers & BUTTON2_MASK) != 0)
 226:           this.button = BUTTON2;
 227:         else if ((modifiers & BUTTON3_MASK) != 0)
 228:           this.button = BUTTON3;
 229:       }
 230:   }
 231: 
 232:   /**
 233:    * Initializes a new instance of <code>MouseEvent</code> with the specified
 234:    * information. Note that an invalid id leads to unspecified results.
 235:    *
 236:    * @param source the source of the event
 237:    * @param id the event id
 238:    * @param when the timestamp of when the event occurred
 239:    * @param modifiers the modifier keys during the event, in old or new style
 240:    * @param x the X coordinate of the mouse point
 241:    * @param y the Y coordinate of the mouse point
 242:    * @param clickCount the number of mouse clicks for this event
 243:    * @param popupTrigger true if this event triggers a popup menu
 244:    * @throws IllegalArgumentException if source is null
 245:    */
 246:   public MouseEvent(Component source, int id, long when, int modifiers,
 247:                     int x, int y, int clickCount, boolean popupTrigger)
 248:   {
 249:     this(source, id, when, modifiers, x, y, clickCount, popupTrigger,
 250:          NOBUTTON);
 251:   }
 252: 
 253:   /**
 254:    * This method returns the X coordinate of the mouse position. This is
 255:    * relative to the source component.
 256:    *
 257:    * @return the x coordinate
 258:    */
 259:   public int getX()
 260:   {
 261:     return x;
 262:   }
 263: 
 264:   /**
 265:    * This method returns the Y coordinate of the mouse position. This is
 266:    * relative to the source component.
 267:    *
 268:    * @return the y coordinate
 269:    */
 270:   public int getY()
 271:   {
 272:     return y;
 273:   }
 274: 
 275:   /**
 276:    * This method returns a <code>Point</code> for the x,y position of
 277:    * the mouse pointer. This is relative to the source component.
 278:    *
 279:    * @return a <code>Point</code> for the event position
 280:    */
 281:   public Point getPoint()
 282:   {
 283:     return new Point(x, y);
 284:   }
 285: 
 286:   /**
 287:    * Translates the event coordinates by the specified x and y offsets.
 288:    *
 289:    * @param dx the value to add to the X coordinate of this event
 290:    * @param dy the value to add to the Y coordiante of this event
 291:    */
 292:   public void translatePoint(int dx, int dy)
 293:   {
 294:     x += dx;
 295:     y += dy;
 296:   }
 297: 
 298:   /**
 299:    * This method returns the number of mouse clicks associated with this
 300:    * event.
 301:    *
 302:    * @return the number of mouse clicks for this event
 303:    */
 304:   public int getClickCount()
 305:   {
 306:     return clickCount;
 307:   }
 308: 
 309:   /**
 310:    * Returns which button, if any, was the most recent to change state. This
 311:    * will be one of {@link #NOBUTTON}, {@link #BUTTON1}, {@link #BUTTON2}, or
 312:    * {@link #BUTTON3}.
 313:    *
 314:    * @return the button that changed state
 315:    * @since 1.4
 316:    */
 317:   public int getButton()
 318:   {
 319:     return button;
 320:   }
 321: 
 322:   /**
 323:    * This method tests whether or not the event is a popup menu trigger. This
 324:    * should be checked in both MousePressed and MouseReleased to be
 325:    * cross-platform compatible, as different systems have different popup
 326:    * triggers.
 327:    *
 328:    * @return true if the event is a popup menu trigger
 329:    */
 330:   public boolean isPopupTrigger()
 331:   {
 332:     return popupTrigger;
 333:   }
 334: 
 335:   /**
 336:    * Returns a string describing the modifiers, such as "Shift" or
 337:    * "Ctrl+Button1".
 338:    *
 339:    * XXX Sun claims this can be localized via the awt.properties file - how
 340:    * do we implement that?
 341:    *
 342:    * @param modifiers the old-style modifiers to convert to text
 343:    * @return a string representation of the modifiers in this bitmask
 344:    */
 345:   public static String getMouseModifiersText(int modifiers)
 346:   {
 347:     modifiers &= EventModifier.OLD_MASK;
 348:     if ((modifiers & BUTTON2_MASK) != 0)
 349:       modifiers |= BUTTON2_DOWN_MASK;
 350:     if ((modifiers & BUTTON3_MASK) != 0)
 351:       modifiers |= BUTTON3_DOWN_MASK;
 352:     return getModifiersExText(EventModifier.extend(modifiers));
 353:   }
 354: 
 355:   /**
 356:    * Returns a string identifying this event. This is formatted as the field
 357:    * name of the id type, followed by the (x,y) point, the most recent button
 358:    * changed, modifiers (if any), extModifiers (if any), and clickCount.
 359:    *
 360:    * @return a string identifying this event
 361:    */
 362:   public String paramString()
 363:   {
 364:     StringBuffer s = new StringBuffer();
 365:     switch (id)
 366:       {
 367:       case MOUSE_CLICKED:
 368:         s.append("MOUSE_CLICKED,(");
 369:         break;
 370:       case MOUSE_PRESSED:
 371:         s.append("MOUSE_PRESSED,(");
 372:         break;
 373:       case MOUSE_RELEASED:
 374:         s.append("MOUSE_RELEASED,(");
 375:         break;
 376:       case MOUSE_MOVED:
 377:         s.append("MOUSE_MOVED,(");
 378:         break;
 379:       case MOUSE_ENTERED:
 380:         s.append("MOUSE_ENTERED,(");
 381:         break;
 382:       case MOUSE_EXITED:
 383:         s.append("MOUSE_EXITED,(");
 384:         break;
 385:       case MOUSE_DRAGGED:
 386:         s.append("MOUSE_DRAGGED,(");
 387:         break;
 388:       case MOUSE_WHEEL:
 389:         s.append("MOUSE_WHEEL,(");
 390:         break;
 391:       default:
 392:         s.append("unknown type,(");
 393:       }
 394:     s.append(x).append(',').append(y).append("),button=").append(button);
 395:     if ((modifiers & EventModifier.NEW_MASK) != 0)
 396:       {
 397:         int mod = modifiers;
 398:         if ((mod & (ALT_DOWN_MASK | BUTTON2_DOWN_MASK)) != 0)
 399:           mod |= ALT_DOWN_MASK | BUTTON2_DOWN_MASK;
 400:         if ((mod & (META_DOWN_MASK | BUTTON3_DOWN_MASK)) != 0)
 401:           mod |= META_DOWN_MASK | BUTTON3_DOWN_MASK;
 402:         s.append(",modifiers=").append(getModifiersExText(mod));
 403:       }
 404:     if (modifiers != 0)
 405:       s.append(",extModifiers=").append(getModifiersExText(modifiers));
 406:     return s.append(",clickCount=").append(clickCount).toString();
 407:   }
 408: 
 409:   /**
 410:    * Reads in the object from a serial stream.
 411:    *
 412:    * @param s the stream to read from
 413:    * @throws IOException if deserialization fails
 414:    * @throws ClassNotFoundException if deserialization fails
 415:    * @serialData default, except that the modifiers are converted to new style
 416:    */
 417:   private void readObject(ObjectInputStream s)
 418:     throws IOException, ClassNotFoundException
 419:   {
 420:     s.defaultReadObject();
 421:     if ((modifiers & EventModifier.OLD_MASK) != 0)
 422:       {
 423:         if ((modifiers & BUTTON1_MASK) != 0)
 424:           button = BUTTON1;
 425:         else if ((modifiers & BUTTON2_MASK) != 0)
 426:           button = BUTTON2;
 427:         else if ((modifiers & BUTTON3_MASK) != 0)
 428:           button = BUTTON3;
 429:         modifiers = EventModifier.extend(modifiers);
 430:       }
 431:   }
 432: } // class MouseEvent