KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > dnd > DragSource


1 /*
2  * @(#)DragSource.java 1.45 04/05/05
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.awt.dnd;
9
10 import java.awt.AWTError JavaDoc;
11 import java.awt.AWTException JavaDoc;
12 import java.awt.event.InputEvent JavaDoc;
13 import java.awt.AWTPermission JavaDoc;
14 import java.awt.Component JavaDoc;
15 import java.awt.Cursor JavaDoc;
16 import java.awt.GraphicsEnvironment JavaDoc;
17 import java.awt.HeadlessException JavaDoc;
18 import java.awt.Image JavaDoc;
19 import java.awt.Point JavaDoc;
20 import java.awt.Toolkit JavaDoc;
21 import java.awt.datatransfer.FlavorMap JavaDoc;
22 import java.awt.datatransfer.SystemFlavorMap JavaDoc;
23 import java.awt.datatransfer.Transferable JavaDoc;
24 import java.awt.dnd.peer.DragSourceContextPeer;
25 import java.io.Serializable JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.ObjectInputStream JavaDoc;
28 import java.io.ObjectOutputStream JavaDoc;
29 import java.io.Serializable JavaDoc;
30 import java.security.AccessController JavaDoc;
31 import java.util.EventListener JavaDoc;
32 import sun.awt.dnd.SunDragSourceContextPeer;
33 import sun.security.action.GetIntegerAction;
34
35
36 /**
37  * The <code>DragSource</code> is the entity responsible
38  * for the initiation of the Drag
39  * and Drop operation, and may be used in a number of scenarios:
40  * <UL>
41  * <LI>1 default instance per JVM for the lifetime of that JVM.
42  * <LI>1 instance per class of potential Drag Initiator object (e.g
43  * TextField). [implementation dependent]
44  * <LI>1 per instance of a particular
45  * <code>Component</code>, or application specific
46  * object associated with a <code>Component</code>
47  * instance in the GUI. [implementation dependent]
48  * <LI>Some other arbitrary association. [implementation dependent]
49  *</UL>
50  *
51  * Once the <code>DragSource</code> is
52  * obtained, a <code>DragGestureRecognizer</code> should
53  * also be obtained to associate the <code>DragSource</code>
54  * with a particular
55  * <code>Component</code>.
56  * <P>
57  * The initial interpretation of the user's gesture,
58  * and the subsequent starting of the drag operation
59  * are the responsibility of the implementing
60  * <code>Component</code>, which is usually
61  * implemented by a <code>DragGestureRecognizer</code>.
62  *<P>
63  * When a drag gesture occurs, the
64  * <code>DragSource</code>'s
65  * startDrag() method shall be
66  * invoked in order to cause processing
67  * of the user's navigational
68  * gestures and delivery of Drag and Drop
69  * protocol notifications. A
70  * <code>DragSource</code> shall only
71  * permit a single Drag and Drop operation to be
72  * current at any one time, and shall
73  * reject any further startDrag() requests
74  * by throwing an <code>IllegalDnDOperationException</code>
75  * until such time as the extant operation is complete.
76  * <P>
77  * The startDrag() method invokes the
78  * createDragSourceContext() method to
79  * instantiate an appropriate
80  * <code>DragSourceContext</code>
81  * and associate the <code>DragSourceContextPeer</code>
82  * with that.
83  * <P>
84  * If the Drag and Drop System is
85  * unable to initiate a drag operation for
86  * some reason, the startDrag() method throws
87  * a <code>java.awt.dnd.InvalidDnDOperationException</code>
88  * to signal such a condition. Typically this
89  * exception is thrown when the underlying platform
90  * system is either not in a state to
91  * initiate a drag, or the parameters specified are invalid.
92  * <P>
93  * Note that during the drag, the
94  * set of operations exposed by the source
95  * at the start of the drag operation may not change
96  * until the operation is complete.
97  * The operation(s) are constant for the
98  * duration of the operation with respect to the
99  * <code>DragSource</code>.
100  *
101  * @version 1.45, 05/05/04
102  * @since 1.2
103  */

104
105 public class DragSource implements Serializable JavaDoc {
106
107     private static final long serialVersionUID = 6236096958971414066L;
108
109     /*
110      * load a system default cursor
111      */

112
113     private static Cursor JavaDoc load(String JavaDoc name) {
114         if (GraphicsEnvironment.isHeadless()) {
115             return null;
116         }
117
118     try {
119         return (Cursor JavaDoc)Toolkit.getDefaultToolkit().getDesktopProperty(name);
120     } catch (Exception JavaDoc e) {
121         e.printStackTrace();
122
123         throw new RuntimeException JavaDoc("failed to load system cursor: " + name + " : " + e.getMessage());
124     }
125     }
126
127    
128     /**
129      * The default <code>Cursor</code> to use with a copy operation indicating
130      * that a drop is currently allowed. <code>null</code> if
131      * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
132      *
133      * @see java.awt.GraphicsEnvironment#isHeadless
134      */

135     public static final Cursor JavaDoc DefaultCopyDrop =
136         load("DnD.Cursor.CopyDrop");
137
138     /**
139      * The default <code>Cursor</code> to use with a move operation indicating
140      * that a drop is currently allowed. <code>null</code> if
141      * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
142      *
143      * @see java.awt.GraphicsEnvironment#isHeadless
144      */

145     public static final Cursor JavaDoc DefaultMoveDrop =
146         load("DnD.Cursor.MoveDrop");
147
148     /**
149      * The default <code>Cursor</code> to use with a link operation indicating
150      * that a drop is currently allowed. <code>null</code> if
151      * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
152      *
153      * @see java.awt.GraphicsEnvironment#isHeadless
154      */

155     public static final Cursor JavaDoc DefaultLinkDrop =
156         load("DnD.Cursor.LinkDrop");
157
158     /**
159      * The default <code>Cursor</code> to use with a copy operation indicating
160      * that a drop is currently not allowed. <code>null</code> if
161      * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
162      *
163      * @see java.awt.GraphicsEnvironment#isHeadless
164      */

165     public static final Cursor JavaDoc DefaultCopyNoDrop =
166         load("DnD.Cursor.CopyNoDrop");
167
168     /**
169      * The default <code>Cursor</code> to use with a move operation indicating
170      * that a drop is currently not allowed. <code>null</code> if
171      * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
172      *
173      * @see java.awt.GraphicsEnvironment#isHeadless
174      */

175     public static final Cursor JavaDoc DefaultMoveNoDrop =
176         load("DnD.Cursor.MoveNoDrop");
177
178     /**
179      * The default <code>Cursor</code> to use with a link operation indicating
180      * that a drop is currently not allowed. <code>null</code> if
181      * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
182      *
183      * @see java.awt.GraphicsEnvironment#isHeadless
184      */

185     public static final Cursor JavaDoc DefaultLinkNoDrop =
186         load("DnD.Cursor.LinkNoDrop");
187
188     private static final DragSource JavaDoc dflt =
189         (GraphicsEnvironment.isHeadless()) ? null : new DragSource JavaDoc();
190
191     /**
192      * Internal constants for serialization.
193      */

194     static final String JavaDoc dragSourceListenerK = "dragSourceL";
195     static final String JavaDoc dragSourceMotionListenerK = "dragSourceMotionL";
196
197     /**
198      * Gets the <code>DragSource</code> object associated with
199      * the underlying platform.
200      *
201      * @return the platform DragSource
202      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
203      * returns true
204      * @see java.awt.GraphicsEnvironment#isHeadless
205      */

206     public static DragSource JavaDoc getDefaultDragSource() {
207         if (GraphicsEnvironment.isHeadless()) {
208             throw new HeadlessException JavaDoc();
209         } else {
210             return dflt;
211         }
212     }
213
214     /**
215      * Reports
216      * whether or not drag
217      * <code>Image</code> support
218      * is available on the underlying platform.
219      * <P>
220      * @return if the Drag Image support is available on this platform
221      */

222
223     public static boolean isDragImageSupported() {
224     Toolkit JavaDoc t = Toolkit.getDefaultToolkit();
225
226     Boolean JavaDoc supported;
227
228     try {
229         supported = (Boolean JavaDoc)Toolkit.getDefaultToolkit().getDesktopProperty("DnD.isDragImageSupported");
230
231         return supported.booleanValue();
232     } catch (Exception JavaDoc e) {
233         return false;
234     }
235     }
236
237     /**
238      * Creates a new <code>DragSource</code>.
239      *
240      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
241      * returns true
242      * @see java.awt.GraphicsEnvironment#isHeadless
243      */

244     public DragSource() throws HeadlessException JavaDoc {
245         if (GraphicsEnvironment.isHeadless()) {
246             throw new HeadlessException JavaDoc();
247         }
248     }
249
250     /**
251      * Start a drag, given the <code>DragGestureEvent</code>
252      * that initiated the drag, the initial
253      * <code>Cursor</code> to use,
254      * the <code>Image</code> to drag,
255      * the offset of the <code>Image</code> origin
256      * from the hotspot of the <code>Cursor</code> at
257      * the instant of the trigger,
258      * the <code>Transferable</code> subject data
259      * of the drag, the <code>DragSourceListener</code>,
260      * and the <code>FlavorMap</code>.
261      * <P>
262      * @param trigger the <code>DragGestureEvent</code> that initiated the drag
263      * @param dragCursor the initial <code>Cursor</code> or <code>null</code> for defaults
264      * @param dragImage the image to drag or null,
265      * @param imageOffset the offset of the <code>Image</code> origin from the hotspot
266      * of the <code>Cursor</code> at the instant of the trigger
267      * @param transferable the subject data of the drag
268      * @param dsl the <code>DragSourceListener</code>
269      * @param flavorMap the <code>FlavorMap</code> to use, or <code>null</code>
270      * <P>
271      * @throws <code>java.awt.dnd.InvalidDnDOperationException</code>
272      * if the Drag and Drop
273      * system is unable to initiate a drag operation, or if the user
274      * attempts to start a drag while an existing drag operation
275      * is still executing
276      */

277
278     public void startDrag(DragGestureEvent JavaDoc trigger,
279               Cursor JavaDoc dragCursor,
280               Image JavaDoc dragImage,
281               Point JavaDoc imageOffset,
282               Transferable JavaDoc transferable,
283               DragSourceListener JavaDoc dsl,
284               FlavorMap JavaDoc flavorMap) throws InvalidDnDOperationException JavaDoc {
285
286         SunDragSourceContextPeer.setDragDropInProgress(true);
287
288         try {
289             if (flavorMap != null) this.flavorMap = flavorMap;
290
291             DragSourceContextPeer dscp = Toolkit.getDefaultToolkit().createDragSourceContextPeer(trigger);
292
293             DragSourceContext JavaDoc dsc = createDragSourceContext(dscp,
294                                                                 trigger,
295                                                                 dragCursor,
296                                                                 dragImage,
297                                                                 imageOffset,
298                                                                 transferable,
299                                                                 dsl
300                                                                 );
301             
302             if (dsc == null) {
303                 throw new InvalidDnDOperationException JavaDoc();
304             }
305                                 
306             dscp.startDrag(dsc, dsc.getCursor(), dragImage, imageOffset); // may throw
307
} catch (RuntimeException JavaDoc e) {
308             SunDragSourceContextPeer.setDragDropInProgress(false);
309             throw e;
310         }
311     }
312
313     /**
314      * Start a drag, given the <code>DragGestureEvent</code>
315      * that initiated the drag, the initial
316      * <code>Cursor</code> to use,
317      * the <code>Transferable</code> subject data
318      * of the drag, the <code>DragSourceListener</code>,
319      * and the <code>FlavorMap</code>.
320      * <P>
321      * @param trigger the <code>DragGestureEvent</code> that
322      * initiated the drag
323      * @param dragCursor the initial <code>Cursor</code> or
324      * <code>null</code> for defaults
325      * @param transferable the subject data of the drag
326      * @param dsl the <code>DragSourceListener</code>
327      * @param flavorMap the <code>FlavorMap</code> to use or <code>null</code>
328      * <P>
329      * @throws <code>java.awt.dnd.InvalidDnDOperationException</code>
330      * if the Drag and Drop
331      * system is unable to initiate a drag operation, or if the user
332      * attempts to start a drag while an existing drag operation
333      * is still executing
334      */

335
336     public void startDrag(DragGestureEvent JavaDoc trigger,
337               Cursor JavaDoc dragCursor,
338               Transferable JavaDoc transferable,
339               DragSourceListener JavaDoc dsl,
340               FlavorMap JavaDoc flavorMap) throws InvalidDnDOperationException JavaDoc {
341     startDrag(trigger, dragCursor, null, null, transferable, dsl, flavorMap);
342     }
343
344     /**
345      * Start a drag, given the <code>DragGestureEvent</code>
346      * that initiated the drag, the initial <code>Cursor</code>
347      * to use,
348      * the <code>Image</code> to drag,
349      * the offset of the <code>Image</code> origin
350      * from the hotspot of the <code>Cursor</code>
351      * at the instant of the trigger,
352      * the subject data of the drag, and
353      * the <code>DragSourceListener</code>.
354      * <P>
355      * @param trigger the <code>DragGestureEvent</code> that initiated the drag
356      * @param dragCursor the initial <code>Cursor</code> or <code>null</code> for defaults
357      * @param dragImage the <code>Image</code> to drag or <code>null</code>
358      * @param dragOffset the offset of the <code>Image</code> origin from the hotspot
359      * of the <code>Cursor</code> at the instant of the trigger
360      * @param transferable the subject data of the drag
361      * @param dsl the <code>DragSourceListener</code>
362      * <P>
363      * @throws <code>java.awt.dnd.InvalidDnDOperationException</code>
364      * if the Drag and Drop
365      * system is unable to initiate a drag operation, or if the user
366      * attempts to start a drag while an existing drag operation
367      * is still executing
368      */

369
370     public void startDrag(DragGestureEvent JavaDoc trigger,
371               Cursor JavaDoc dragCursor,
372               Image JavaDoc dragImage,
373               Point JavaDoc dragOffset,
374               Transferable JavaDoc transferable,
375               DragSourceListener JavaDoc dsl) throws InvalidDnDOperationException JavaDoc {
376     startDrag(trigger, dragCursor, dragImage, dragOffset, transferable, dsl, null);
377     }
378
379     /**
380      * Start a drag, given the <code>DragGestureEvent</code>
381      * that initiated the drag, the initial
382      * <code>Cursor</code> to
383      * use,
384      * the <code>Transferable</code> subject data
385      * of the drag, and the <code>DragSourceListener</code>.
386      * <P>
387      * @param trigger the <code>DragGestureEvent</code> that initiated the drag
388      * @param dragCursor the initial <code>Cursor</code> or <code>null</code> for defaults
389      * @param transferable the subject data of the drag
390      * @param dsl the <code>DragSourceListener</code>
391      * <P>
392      * @throws <code>java.awt.dnd.InvalidDnDOperationException</code>
393      * if the Drag and Drop
394      * system is unable to initiate a drag operation, or if the user
395      * attempts to start a drag while an existing drag operation
396      * is still executing
397      */

398
399     public void startDrag(DragGestureEvent JavaDoc trigger,
400               Cursor JavaDoc dragCursor,
401               Transferable JavaDoc transferable,
402               DragSourceListener JavaDoc dsl) throws InvalidDnDOperationException JavaDoc {
403     startDrag(trigger, dragCursor, null, null, transferable, dsl, null);
404     }
405
406     /**
407      * Creates the <code>DragSourceContext</code> to handle this drag.
408      * <p>
409      * To incorporate a new <code>DragSourceContext</code>
410      * subclass, subclass <code>DragSource</code> and
411      * override this method.
412      * <p>
413      * If <code>dragImage</code> is <code>null</code>, no image is used
414      * to represent the drag over feedback for this drag operation, but
415      * <code>NullPointerException</code> is not thrown.
416      * <p>
417      * If <code>dsl</code> is <code>null</code>, no drag source listener
418      * is registered with the created <code>DragSourceContext</code>,
419      * but <code>NullPointerException</code> is not thrown.
420      * <p>
421      * If <code>dragCursor</code> is <code>null</code>, the default drag
422      * cursors are used for this drag operation.
423      * <code>NullPointerException</code> is not thrown.
424      *
425      * @param dscp The <code>DragSourceContextPeer</code> for this drag
426      * @param dgl The <code>DragGestureEvent</code> that triggered the
427      * drag
428      * @param dragCursor The initial <code>Cursor</code> to display
429      * @param dragImage The <code>Image</code> to drag or <code>null</code>
430      * @param imageOffset The offset of the <code>Image</code> origin from the
431      * hotspot of the cursor at the instant of the trigger
432      * @param t The subject data of the drag
433      * @param dsl The <code>DragSourceListener</code>
434      *
435      * @return the <code>DragSourceContext</code>
436      *
437      * @throws NullPointerException if <code>dscp</code> is <code>null</code>
438      * @throws NullPointerException if <code>dgl</code> is <code>null</code>
439      * @throws NullPointerException if <code>dragImage</code> is not
440      * <code>null</code> and <code>imageOffset</code> is <code>null</code>
441      * @throws NullPointerException if <code>t</code> is <code>null</code>
442      * @throws IllegalArgumentException if the <code>Component</code>
443      * associated with the trigger event is <code>null</code>.
444      * @throws IllegalArgumentException if the <code>DragSource</code> for the
445      * trigger event is <code>null</code>.
446      * @throws IllegalArgumentException if the drag action for the
447      * trigger event is <code>DnDConstants.ACTION_NONE</code>.
448      * @throws IllegalArgumentException if the source actions for the
449      * <code>DragGestureRecognizer</code> associated with the trigger
450      * event are equal to <code>DnDConstants.ACTION_NONE</code>.
451      */

452
453     protected DragSourceContext JavaDoc createDragSourceContext(DragSourceContextPeer dscp, DragGestureEvent JavaDoc dgl, Cursor JavaDoc dragCursor, Image JavaDoc dragImage, Point JavaDoc imageOffset, Transferable JavaDoc t, DragSourceListener JavaDoc dsl) {
454     return new DragSourceContext JavaDoc(dscp, dgl, dragCursor, dragImage, imageOffset, t, dsl);
455     }
456
457     /**
458      * This method returns the
459      * <code>FlavorMap</code> for this <code>DragSource</code>.
460      * <P>
461      * @return the <code>FlavorMap</code> for this <code>DragSource</code>
462      */

463
464     public FlavorMap JavaDoc getFlavorMap() { return flavorMap; }
465
466     /**
467      * Creates a new <code>DragGestureRecognizer</code>
468      * that implements the specified
469      * abstract subclass of
470      * <code>DragGestureRecognizer</code>, and
471      * sets the specified <code>Component</code>
472      * and <code>DragGestureListener</code> on
473      * the newly created object.
474      * <P>
475      * @param recognizerAbstractClass the requested abstract type
476      * @param actions the permitted source drag actions
477      * @param c the <code>Component</code> target
478      * @param dgl the <code>DragGestureListener</code> to notify
479      * <P>
480      * @return the new <code>DragGestureRecognizer</code> or <code>null</code>
481      * if the <code>Toolkit.createDragGestureRecognizer</code> method
482      * has no implementation available for
483      * the requested <code>DragGestureRecognizer</code>
484      * subclass and returns <code>null</code>
485      */

486
487     public <T extends DragGestureRecognizer JavaDoc> T
488     createDragGestureRecognizer(Class JavaDoc<T> recognizerAbstractClass,
489                     Component JavaDoc c, int actions,
490                     DragGestureListener JavaDoc dgl)
491     {
492     return Toolkit.getDefaultToolkit().createDragGestureRecognizer(recognizerAbstractClass, this, c, actions, dgl);
493     }
494
495     
496     /**
497      * Creates a new <code>DragGestureRecognizer</code>
498      * that implements the default
499      * abstract subclass of <code>DragGestureRecognizer</code>
500      * for this <code>DragSource</code>,
501      * and sets the specified <code>Component</code>
502      * and <code>DragGestureListener</code> on the
503      * newly created object.
504      *
505      * For this <code>DragSource</code>
506      * the default is <code>MouseDragGestureRecognizer</code>.
507      * <P>
508      * @param c the <code>Component</code> target for the recognizer
509      * @param actions the permitted source actions
510      * @param dgl the <code>DragGestureListener</code> to notify
511      * <P>
512      * @return the new <code>DragGestureRecognizer</code> or <code>null</code>
513      * if the <code>Toolkit.createDragGestureRecognizer</code> method
514      * has no implementation available for
515      * the requested <code>DragGestureRecognizer</code>
516      * subclass and returns <code>null</code>
517      */

518
519     public DragGestureRecognizer JavaDoc createDefaultDragGestureRecognizer(Component JavaDoc c, int actions, DragGestureListener JavaDoc dgl) {
520     return Toolkit.getDefaultToolkit().createDragGestureRecognizer(MouseDragGestureRecognizer JavaDoc.class, this, c, actions, dgl);
521     }
522
523     /**
524      * Adds the specified <code>DragSourceListener</code> to this
525      * <code>DragSource</code> to receive drag source events during drag
526      * operations intiated with this <code>DragSource</code>.
527      * If a <code>null</code> listener is specified, no action is taken and no
528      * exception is thrown.
529      *
530      * @param dsl the <code>DragSourceListener</code> to add
531      *
532      * @see #removeDragSourceListener
533      * @see #getDragSourceListeners
534      * @since 1.4
535      */

536     public void addDragSourceListener(DragSourceListener JavaDoc dsl) {
537     if (dsl != null) {
538             synchronized (this) {
539                 listener = DnDEventMulticaster.add(listener, dsl);
540             }
541         }
542     }
543
544     /**
545      * Removes the specified <code>DragSourceListener</code> from this
546      * <code>DragSource</code>.
547      * If a <code>null</code> listener is specified, no action is taken and no
548      * exception is thrown.
549      * If the listener specified by the argument was not previously added to
550      * this <code>DragSource</code>, no action is taken and no exception
551      * is thrown.
552      *
553      * @param dsl the <code>DragSourceListener</code> to remove
554      *
555      * @see #addDragSourceListener
556      * @see #getDragSourceListeners
557      * @since 1.4
558      */

559     public void removeDragSourceListener(DragSourceListener JavaDoc dsl) {
560         if (dsl != null) {
561             synchronized (this) {
562                 listener = DnDEventMulticaster.remove(listener, dsl);
563             }
564         }
565     }
566
567     /**
568      * Gets all the <code>DragSourceListener</code>s
569      * registered with this <code>DragSource</code>.
570      *
571      * @return all of this <code>DragSource</code>'s
572      * <code>DragSourceListener</code>s or an empty array if no
573      * such listeners are currently registered
574      *
575      * @see #addDragSourceListener
576      * @see #removeDragSourceListener
577      * @since 1.4
578      */

579     public DragSourceListener JavaDoc[] getDragSourceListeners() {
580         return (DragSourceListener JavaDoc[])getListeners(DragSourceListener JavaDoc.class);
581     }
582
583     /**
584      * Adds the specified <code>DragSourceMotionListener</code> to this
585      * <code>DragSource</code> to receive drag motion events during drag
586      * operations intiated with this <code>DragSource</code>.
587      * If a <code>null</code> listener is specified, no action is taken and no
588      * exception is thrown.
589      *
590      * @param dsml the <code>DragSourceMotionListener</code> to add
591      *
592      * @see #removeDragSourceMotionListener
593      * @see #getDragSourceMotionListeners
594      * @since 1.4
595      */

596     public void addDragSourceMotionListener(DragSourceMotionListener JavaDoc dsml) {
597     if (dsml != null) {
598             synchronized (this) {
599                 motionListener = DnDEventMulticaster.add(motionListener, dsml);
600             }
601         }
602     }
603
604     /**
605      * Removes the specified <code>DragSourceMotionListener</code> from this
606      * <code>DragSource</code>.
607      * If a <code>null</code> listener is specified, no action is taken and no
608      * exception is thrown.
609      * If the listener specified by the argument was not previously added to
610      * this <code>DragSource</code>, no action is taken and no exception
611      * is thrown.
612      *
613      * @param dsml the <code>DragSourceMotionListener</code> to remove
614      *
615      * @see #addDragSourceMotionListener
616      * @see #getDragSourceMotionListeners
617      * @since 1.4
618      */

619     public void removeDragSourceMotionListener(DragSourceMotionListener JavaDoc dsml) {
620         if (dsml != null) {
621             synchronized (this) {
622                 motionListener = DnDEventMulticaster.remove(motionListener, dsml);
623             }
624         }
625     }
626
627     /**
628      * Gets all of the <code>DragSourceMotionListener</code>s
629      * registered with this <code>DragSource</code>.
630      *
631      * @return all of this <code>DragSource</code>'s
632      * <code>DragSourceMotionListener</code>s or an empty array if no
633      * such listeners are currently registered
634      *
635      * @see #addDragSourceMotionListener
636      * @see #removeDragSourceMotionListener
637      * @since 1.4
638      */

639     public DragSourceMotionListener JavaDoc[] getDragSourceMotionListeners() {
640         return (DragSourceMotionListener JavaDoc[])
641             getListeners(DragSourceMotionListener JavaDoc.class);
642     }
643
644     /**
645      * Gets all the objects currently registered as
646      * <code><em>Foo</em>Listener</code>s upon this <code>DragSource</code>.
647      * <code><em>Foo</em>Listener</code>s are registered using the
648      * <code>add<em>Foo</em>Listener</code> method.
649      *
650      * @param listenerType the type of listeners requested; this parameter
651      * should specify an interface that descends from
652      * <code>java.util.EventListener</code>
653      * @return an array of all objects registered as
654      * <code><em>Foo</em>Listener</code>s on this
655      * <code>DragSource</code>, or an empty array if no such listeners
656      * have been added
657      * @exception <code>ClassCastException</code> if <code>listenerType</code>
658      * doesn't specify a class or interface that implements
659      * <code>java.util.EventListener</code>
660      *
661      * @see #getDragSourceListeners
662      * @see #getDragSourceMotionListeners
663      * @since 1.4
664      */

665     public <T extends EventListener JavaDoc> T[] getListeners(Class JavaDoc<T> listenerType) {
666         EventListener JavaDoc l = null;
667         if (listenerType == DragSourceListener JavaDoc.class) {
668             l = listener;
669         } else if (listenerType == DragSourceMotionListener JavaDoc.class) {
670             l = motionListener;
671         }
672         return DnDEventMulticaster.getListeners(l, listenerType);
673     }
674
675     /**
676      * This method calls <code>dragEnter</code> on the
677      * <code>DragSourceListener</code>s registered with this
678      * <code>DragSource</code>, and passes them the specified
679      * <code>DragSourceDragEvent</code>.
680      *
681      * @param dsde the <code>DragSourceDragEvent</code>
682      */

683     void processDragEnter(DragSourceDragEvent JavaDoc dsde) {
684         DragSourceListener JavaDoc dsl = listener;
685         if (dsl != null) {
686             dsl.dragEnter(dsde);
687         }
688     }
689
690     /**
691      * This method calls <code>dragOver</code> on the
692      * <code>DragSourceListener</code>s registered with this
693      * <code>DragSource</code>, and passes them the specified
694      * <code>DragSourceDragEvent</code>.
695      *
696      * @param dsde the <code>DragSourceDragEvent</code>
697      */

698     void processDragOver(DragSourceDragEvent JavaDoc dsde) {
699         DragSourceListener JavaDoc dsl = listener;
700         if (dsl != null) {
701             dsl.dragOver(dsde);
702         }
703     }
704
705     /**
706      * This method calls <code>dropActionChanged</code> on the
707      * <code>DragSourceListener</code>s registered with this
708      * <code>DragSource</code>, and passes them the specified
709      * <code>DragSourceDragEvent</code>.
710      *
711      * @param dsde the <code>DragSourceDragEvent</code>
712      */

713     void processDropActionChanged(DragSourceDragEvent JavaDoc dsde) {
714         DragSourceListener JavaDoc dsl = listener;
715         if (dsl != null) {
716             dsl.dropActionChanged(dsde);
717         }
718     }
719
720     /**
721      * This method calls <code>dragExit</code> on the
722      * <code>DragSourceListener</code>s registered with this
723      * <code>DragSource</code>, and passes them the specified
724      * <code>DragSourceEvent</code>.
725      *
726      * @param dse the <code>DragSourceEvent</code>
727      */

728     void processDragExit(DragSourceEvent JavaDoc dse) {
729         DragSourceListener JavaDoc dsl = listener;
730         if (dsl != null) {
731             dsl.dragExit(dse);
732         }
733     }
734
735     /**
736      * This method calls <code>dragDropEnd</code> on the
737      * <code>DragSourceListener</code>s registered with this
738      * <code>DragSource</code>, and passes them the specified
739      * <code>DragSourceDropEvent</code>.
740      *
741      * @param dsde the <code>DragSourceEvent</code>
742      */

743     void processDragDropEnd(DragSourceDropEvent JavaDoc dsde) {
744         DragSourceListener JavaDoc dsl = listener;
745         if (dsl != null) {
746             dsl.dragDropEnd(dsde);
747         }
748     }
749
750     /**
751      * This method calls <code>dragMouseMoved</code> on the
752      * <code>DragSourceMotionListener</code>s registered with this
753      * <code>DragSource</code>, and passes them the specified
754      * <code>DragSourceDragEvent</code>.
755      *
756      * @param dsde the <code>DragSourceEvent</code>
757      */

758     void processDragMouseMoved(DragSourceDragEvent JavaDoc dsde) {
759         DragSourceMotionListener JavaDoc dsml = motionListener;
760         if (dsml != null) {
761             dsml.dragMouseMoved(dsde);
762         }
763     }
764
765     /**
766      * Serializes this <code>DragSource</code>. This method first performs
767      * default serialization. Next, it writes out this object's
768      * <code>FlavorMap</code> if and only if it can be serialized. If not,
769      * <code>null</code> is written instead. Next, it writes out
770      * <code>Serializable</code> listeners registered with this
771      * object. Listeners are written in a <code>null</code>-terminated sequence
772      * of 0 or more pairs. The pair consists of a <code>String</code> and an
773      * <code>Object</code>; the <code>String</code> indicates the type of the
774      * <code>Object</code> and is one of the following:
775      * <ul>
776      * <li><code>dragSourceListenerK</code> indicating a
777      * <code>DragSourceListener</code> object;
778      * <li><code>dragSourceMotionListenerK</code> indicating a
779      * <code>DragSourceMotionListener</code> object.
780      * </ul>
781      *
782      * @serialData Either a <code>FlavorMap</code> instance, or
783      * <code>null</code>, followed by a <code>null</code>-terminated
784      * sequence of 0 or more pairs; the pair consists of a
785      * <code>String</code> and an <code>Object</code>; the
786      * <code>String</code> indicates the type of the <code>Object</code>
787      * and is one of the following:
788      * <ul>
789      * <li><code>dragSourceListenerK</code> indicating a
790      * <code>DragSourceListener</code> object;
791      * <li><code>dragSourceMotionListenerK</code> indicating a
792      * <code>DragSourceMotionListener</code> object.
793      * </ul>.
794      * @since 1.4
795      */

796     private void writeObject(ObjectOutputStream JavaDoc s) throws IOException JavaDoc {
797         s.defaultWriteObject();
798
799         s.writeObject(SerializationTester.test(flavorMap) ? flavorMap : null);
800
801         DnDEventMulticaster.save(s, dragSourceListenerK, listener);
802         DnDEventMulticaster.save(s, dragSourceMotionListenerK, motionListener);
803         s.writeObject(null);
804     }
805
806     /**
807      * Deserializes this <code>DragSource</code>. This method first performs
808      * default deserialization. Next, this object's <code>FlavorMap</code> is
809      * deserialized by using the next object in the stream.
810      * If the resulting <code>FlavorMap</code> is <code>null</code>, this
811      * object's <code>FlavorMap</code> is set to the default FlavorMap for
812      * this thread's <code>ClassLoader</code>.
813      * Next, this object's listeners are deserialized by reading a
814      * <code>null</code>-terminated sequence of 0 or more key/value pairs
815      * from the stream:
816      * <ul>
817      * <li>If a key object is a <code>String</code> equal to
818      * <code>dragSourceListenerK</code>, a <code>DragSourceListener</code> is
819      * deserialized using the corresponding value object and added to this
820      * <code>DragSource</code>.
821      * <li>If a key object is a <code>String</code> equal to
822      * <code>dragSourceMotionListenerK</code>, a
823      * <code>DragSourceMotionListener</code> is deserialized using the
824      * corresponding value object and added to this <code>DragSource</code>.
825      * <li>Otherwise, the key/value pair is skipped.
826      * </ul>
827      *
828      * @see java.awt.datatransfer.SystemFlavorMap#getDefaultFlavorMap
829      * @since 1.4
830      */

831     private void readObject(ObjectInputStream JavaDoc s)
832       throws ClassNotFoundException JavaDoc, IOException JavaDoc {
833         s.defaultReadObject();
834
835         // 'flavorMap' was written explicitly
836
flavorMap = (FlavorMap JavaDoc)s.readObject();
837
838         // Implementation assumes 'flavorMap' is never null.
839
if (flavorMap == null) {
840             flavorMap = SystemFlavorMap.getDefaultFlavorMap();
841         }
842
843         Object JavaDoc keyOrNull;
844         while (null != (keyOrNull = s.readObject())) {
845             String JavaDoc key = ((String JavaDoc)keyOrNull).intern();
846
847             if (dragSourceListenerK == key) {
848                 addDragSourceListener((DragSourceListener JavaDoc)(s.readObject()));
849             } else if (dragSourceMotionListenerK == key) {
850                 addDragSourceMotionListener(
851                     (DragSourceMotionListener JavaDoc)(s.readObject()));
852             } else {
853                 // skip value for unrecognized key
854
s.readObject();
855             }
856         }
857     }
858
859     /**
860      * Returns the drag gesture motion threshold. The drag gesture motion threshold
861      * defines the recommended behavior for {@link MouseDragGestureRecognizer}s.
862      * <p>
863      * If the system property <code>awt.dnd.drag.threshold</code> is set to
864      * a positive integer, this method returns the value of the system property;
865      * otherwise if a pertinent desktop property is available and supported by
866      * the implementation of the Java platform, this method returns the value of
867      * that property; otherwise this method returns some default value.
868      * The pertinent desktop property can be queried using
869      * <code>java.awt.Toolkit.getDesktopProperty("DnD.gestureMotionThreshold")</code>.
870      *
871      * @return the drag gesture motion threshold
872      * @see MouseDragGestureRecognizer
873      * @since 1.5
874      */

875     public static int getDragThreshold() {
876         int ts = ((Integer JavaDoc)AccessController.doPrivileged(
877                 new GetIntegerAction("awt.dnd.drag.threshold", 0))).intValue();
878         if (ts > 0) {
879             return ts;
880         } else {
881             Integer JavaDoc td = (Integer JavaDoc)Toolkit.getDefaultToolkit().
882                     getDesktopProperty("DnD.gestureMotionThreshold");
883             if (td != null) {
884                 return td.intValue();
885             }
886         }
887         return 5;
888     }
889
890     /*
891      * fields
892      */

893
894     private transient FlavorMap JavaDoc flavorMap = SystemFlavorMap.getDefaultFlavorMap();
895
896     private transient DragSourceListener JavaDoc listener;
897
898     private transient DragSourceMotionListener JavaDoc motionListener;
899 }
900
Popular Tags