1 /* 2 * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 27 package java.awt.dnd; 28 29 import java.awt.Component; 30 import java.awt.Cursor; 31 32 import java.awt.Image; 33 import java.awt.Point; 34 35 import java.awt.event.InputEvent; 36 37 import java.awt.datatransfer.Transferable; 38 39 import java.io.InvalidObjectException; 40 import java.util.EventObject; 41 42 import java.util.Collections; 43 import java.util.List; 44 import java.util.Iterator; 45 46 import java.io.IOException; 47 import java.io.ObjectInputStream; 48 import java.io.ObjectOutputStream; 49 50 51 /** 52 * A <code>DragGestureEvent</code> is passed 53 * to <code>DragGestureListener</code>'s 54 * dragGestureRecognized() method 55 * when a particular <code>DragGestureRecognizer</code> detects that a 56 * platform dependent drag initiating gesture has occurred 57 * on the <code>Component</code> that it is tracking. 58 * 59 * The {@code action} field of any {@code DragGestureEvent} instance should take one of the following 60 * values: 61 * <ul> 62 * <li> {@code DnDConstants.ACTION_COPY} 63 * <li> {@code DnDConstants.ACTION_MOVE} 64 * <li> {@code DnDConstants.ACTION_LINK} 65 * </ul> 66 * Assigning the value different from listed above will cause an unspecified behavior. 67 * 68 * @see java.awt.dnd.DragGestureRecognizer 69 * @see java.awt.dnd.DragGestureListener 70 * @see java.awt.dnd.DragSource 71 * @see java.awt.dnd.DnDConstants 72 */ 73 74 public class DragGestureEvent extends EventObject { 75 76 private static final long serialVersionUID = 9080172649166731306L; 77 78 /** 79 * Constructs a <code>DragGestureEvent</code> object given by the 80 * <code>DragGestureRecognizer</code> instance firing this event, 81 * an {@code act} parameter representing 82 * the user's preferred action, an {@code ori} parameter 83 * indicating the origin of the drag, and a {@code List} of 84 * events that comprise the gesture({@code evs} parameter). 85 * 86 * @param dgr The <code>DragGestureRecognizer</code> firing this event 87 * @param act The user's preferred action. 88 * For information on allowable values, see 89 * the class description for {@link DragGestureEvent} 90 * @param ori The origin of the drag 91 * @param evs The <code>List</code> of events that comprise the gesture 92 * 93 * @throws IllegalArgumentException if any parameter equals {@code null} 94 * @throws IllegalArgumentException if the act parameter does not comply with 95 * the values given in the class 96 * description for {@link DragGestureEvent} 97 * @see java.awt.dnd.DnDConstants 98 */ 99 100 public DragGestureEvent(DragGestureRecognizer dgr, int act, Point ori, 101 List<? extends InputEvent> evs) 102 { 103 super(dgr); 104 105 if ((component = dgr.getComponent()) == null) 106 throw new IllegalArgumentException("null component"); 107 if ((dragSource = dgr.getDragSource()) == null) 108 throw new IllegalArgumentException("null DragSource"); 109 110 if (evs == null || evs.isEmpty()) 111 throw new IllegalArgumentException("null or empty list of events"); 112 113 if (act != DnDConstants.ACTION_COPY && 114 act != DnDConstants.ACTION_MOVE && 115 act != DnDConstants.ACTION_LINK) 116 throw new IllegalArgumentException("bad action"); 117 118 if (ori == null) throw new IllegalArgumentException("null origin"); 119 120 events = evs; 121 action = act; 122 origin = ori; 123 } 124 125 /** 126 * Returns the source as a <code>DragGestureRecognizer</code>. 127 * 128 * @return the source as a <code>DragGestureRecognizer</code> 129 */ 130 131 public DragGestureRecognizer getSourceAsDragGestureRecognizer() { 132 return (DragGestureRecognizer)getSource(); 133 } 134 135 /** 136 * Returns the <code>Component</code> associated 137 * with this <code>DragGestureEvent</code>. 138 * 139 * @return the Component 140 */ 141 142 public Component getComponent() { return component; } 143 144 /** 145 * Returns the <code>DragSource</code>. 146 * 147 * @return the <code>DragSource</code> 148 */ 149 150 public DragSource getDragSource() { return dragSource; } 151 152 /** 153 * Returns a <code>Point</code> in the coordinates 154 * of the <code>Component</code> over which the drag originated. 155 * 156 * @return the Point where the drag originated in Component coords. 157 */ 158 159 public Point getDragOrigin() { 160 return origin; 161 } 162 163 /** 164 * Returns an <code>Iterator</code> for the events 165 * comprising the gesture. 166 * 167 * @return an Iterator for the events comprising the gesture 168 */ 169 @SuppressWarnings("unchecked") 170 public Iterator<InputEvent> iterator() { return events.iterator(); } 171 172 /** 173 * Returns an <code>Object</code> array of the 174 * events comprising the drag gesture. 175 * 176 * @return an array of the events comprising the gesture 177 */ 178 179 public Object[] toArray() { return events.toArray(); } 180 181 /** 182 * Returns an array of the events comprising the drag gesture. 183 * 184 * @param array the array of <code>EventObject</code> sub(types) 185 * 186 * @return an array of the events comprising the gesture 187 */ 188 @SuppressWarnings("unchecked") 189 public Object[] toArray(Object[] array) { return events.toArray(array); } 190 191 /** 192 * Returns an <code>int</code> representing the 193 * action selected by the user. 194 * 195 * @return the action selected by the user 196 */ 197 198 public int getDragAction() { return action; } 199 200 /** 201 * Returns the initial event that triggered the gesture. 202 * 203 * @return the first "triggering" event in the sequence of the gesture 204 */ 205 206 public InputEvent getTriggerEvent() { 207 return getSourceAsDragGestureRecognizer().getTriggerEvent(); 208 } 209 210 /** 211 * Starts the drag operation given the <code>Cursor</code> for this drag 212 * operation and the <code>Transferable</code> representing the source data 213 * for this drag operation. 214 * <br> 215 * If a <code>null</code> <code>Cursor</code> is specified no exception will 216 * be thrown and default drag cursors will be used instead. 217 * <br> 218 * If a <code>null</code> <code>Transferable</code> is specified 219 * <code>NullPointerException</code> will be thrown. 220 * @param dragCursor The initial {@code Cursor} for this drag operation 221 * or {@code null} for the default cursor handling; 222 * see 223 * <a href="DragSourceContext.html#defaultCursor">DragSourceContext</a> 224 * for more details on the cursor handling mechanism 225 * during drag and drop 226 * @param transferable The <code>Transferable</code> representing the source 227 * data for this drag operation. 228 * 229 * @throws InvalidDnDOperationException if the Drag and Drop 230 * system is unable to initiate a drag operation, or if the user 231 * attempts to start a drag while an existing drag operation is 232 * still executing. 233 * @throws NullPointerException if the {@code Transferable} is {@code null} 234 * @since 1.4 235 */ 236 public void startDrag(Cursor dragCursor, Transferable transferable) 237 throws InvalidDnDOperationException { 238 dragSource.startDrag(this, dragCursor, transferable, null); 239 } 240 241 /** 242 * Starts the drag given the initial <code>Cursor</code> to display, 243 * the <code>Transferable</code> object, 244 * and the <code>DragSourceListener</code> to use. 245 * 246 * @param dragCursor The initial {@code Cursor} for this drag operation 247 * or {@code null} for the default cursor handling; 248 * see 249 * <a href="DragSourceContext.html#defaultCursor">DragSourceContext</a> 250 * for more details on the cursor handling mechanism 251 * during drag and drop 252 * @param transferable The source's Transferable 253 * @param dsl The source's DragSourceListener 254 * 255 * @throws InvalidDnDOperationException if 256 * the Drag and Drop system is unable to 257 * initiate a drag operation, or if the user 258 * attempts to start a drag while an existing 259 * drag operation is still executing. 260 */ 261 262 public void startDrag(Cursor dragCursor, Transferable transferable, DragSourceListener dsl) throws InvalidDnDOperationException { 263 dragSource.startDrag(this, dragCursor, transferable, dsl); 264 } 265 266 /** 267 * Start the drag given the initial <code>Cursor</code> to display, 268 * a drag <code>Image</code>, the offset of 269 * the <code>Image</code>, 270 * the <code>Transferable</code> object, and 271 * the <code>DragSourceListener</code> to use. 272 * 273 * @param dragCursor The initial {@code Cursor} for this drag operation 274 * or {@code null} for the default cursor handling; 275 * see 276 * <a href="DragSourceContext.html#defaultCursor">DragSourceContext</a> 277 * for more details on the cursor handling mechanism 278 * during drag and drop 279 * @param dragImage The source's dragImage 280 * @param imageOffset The dragImage's offset 281 * @param transferable The source's Transferable 282 * @param dsl The source's DragSourceListener 283 * 284 * @throws InvalidDnDOperationException if 285 * the Drag and Drop system is unable to 286 * initiate a drag operation, or if the user 287 * attempts to start a drag while an existing 288 * drag operation is still executing. 289 */ 290 291 public void startDrag(Cursor dragCursor, Image dragImage, Point imageOffset, Transferable transferable, DragSourceListener dsl) throws InvalidDnDOperationException { 292 dragSource.startDrag(this, dragCursor, dragImage, imageOffset, transferable, dsl); 293 } 294 295 /** 296 * Serializes this <code>DragGestureEvent</code>. Performs default 297 * serialization and then writes out this object's <code>List</code> of 298 * gesture events if and only if the <code>List</code> can be serialized. 299 * If not, <code>null</code> is written instead. In this case, a 300 * <code>DragGestureEvent</code> created from the resulting deserialized 301 * stream will contain an empty <code>List</code> of gesture events. 302 * 303 * @serialData The default serializable fields, in alphabetical order, 304 * followed by either a <code>List</code> instance, or 305 * <code>null</code>. 306 * @since 1.4 307 */ 308 private void writeObject(ObjectOutputStream s) throws IOException { 309 s.defaultWriteObject(); 310 311 s.writeObject(SerializationTester.test(events) ? events : null); 312 } 313 314 /** 315 * Deserializes this <code>DragGestureEvent</code>. This method first 316 * performs default deserialization for all non-<code>transient</code> 317 * fields. An attempt is then made to deserialize this object's 318 * <code>List</code> of gesture events as well. This is first attempted 319 * by deserializing the field <code>events</code>, because, in releases 320 * prior to 1.4, a non-<code>transient</code> field of this name stored the 321 * <code>List</code> of gesture events. If this fails, the next object in 322 * the stream is used instead. If the resulting <code>List</code> is 323 * <code>null</code>, this object's <code>List</code> of gesture events 324 * is set to an empty <code>List</code>. 325 * 326 * @since 1.4 327 */ 328 private void readObject(ObjectInputStream s) 329 throws ClassNotFoundException, IOException 330 { 331 ObjectInputStream.GetField f = s.readFields(); 332 333 DragSource newDragSource = (DragSource)f.get("dragSource", null); 334 if (newDragSource == null) { 335 throw new InvalidObjectException("null DragSource"); 336 } 337 dragSource = newDragSource; 338 339 Component newComponent = (Component)f.get("component", null); 340 if (newComponent == null) { 341 throw new InvalidObjectException("null component"); 342 } 343 component = newComponent; 344 345 Point newOrigin = (Point)f.get("origin", null); 346 if (newOrigin == null) { 347 throw new InvalidObjectException("null origin"); 348 } 349 origin = newOrigin; 350 351 int newAction = f.get("action", 0); 352 if (newAction != DnDConstants.ACTION_COPY && 353 newAction != DnDConstants.ACTION_MOVE && 354 newAction != DnDConstants.ACTION_LINK) { 355 throw new InvalidObjectException("bad action"); 356 } 357 action = newAction; 358 359 // Pre-1.4 support. 'events' was previously non-transient 360 @SuppressWarnings("rawtypes") 361 List newEvents; 362 try { 363 newEvents = (List)f.get("events", null); 364 } catch (IllegalArgumentException e) { 365 // 1.4-compatible byte stream. 'events' was written explicitly 366 newEvents = (List)s.readObject(); 367 } 368 369 // Implementation assumes 'events' is never null. 370 if (newEvents != null && newEvents.isEmpty()) { 371 // Constructor treats empty events list as invalid value 372 // Throw exception if serialized list is empty 373 throw new InvalidObjectException("empty list of events"); 374 } else if (newEvents == null) { 375 newEvents = Collections.emptyList(); 376 } 377 events = newEvents; 378 } 379 380 /* 381 * fields 382 */ 383 @SuppressWarnings("rawtypes") 384 private transient List events; 385 386 /** 387 * The DragSource associated with this DragGestureEvent. 388 * 389 * @serial 390 */ 391 private DragSource dragSource; 392 393 /** 394 * The Component associated with this DragGestureEvent. 395 * 396 * @serial 397 */ 398 private Component component; 399 400 /** 401 * The origin of the drag. 402 * 403 * @serial 404 */ 405 private Point origin; 406 407 /** 408 * The user's preferred action. 409 * 410 * @serial 411 */ 412 private int action; 413 }