blob: 5995c885b2f51843cef762fdd50368bdc3efc356 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package java.awt.dnd;
27
28import java.util.TooManyListenersException;
29
30import java.io.IOException;
31import java.io.ObjectInputStream;
32import java.io.ObjectOutputStream;
33import java.io.Serializable;
34
35import java.awt.Component;
36import java.awt.Dimension;
37import java.awt.GraphicsEnvironment;
38import java.awt.HeadlessException;
39import java.awt.Insets;
40import java.awt.Point;
41import java.awt.Rectangle;
42import java.awt.Toolkit;
43import java.awt.event.ActionEvent;
44import java.awt.event.ActionListener;
45import java.awt.datatransfer.FlavorMap;
46import java.awt.datatransfer.SystemFlavorMap;
47import javax.swing.Timer;
48import java.awt.peer.ComponentPeer;
49import java.awt.peer.LightweightPeer;
50import java.awt.dnd.peer.DropTargetPeer;
51
52
53/**
54 * The <code>DropTarget</code> is associated
55 * with a <code>Component</code> when that <code>Component</code>
56 * wishes
57 * to accept drops during Drag and Drop operations.
58 * <P>
59 * Each
60 * <code>DropTarget</code> is associated with a <code>FlavorMap</code>.
61 * The default <code>FlavorMap</code> hereafter designates the
62 * <code>FlavorMap</code> returned by <code>SystemFlavorMap.getDefaultFlavorMap()</code>.
63 *
64 * @since 1.2
65 */
66
67public class DropTarget implements DropTargetListener, Serializable {
68
69 private static final long serialVersionUID = -6283860791671019047L;
70
71 /**
72 * Creates a new DropTarget given the <code>Component</code>
73 * to associate itself with, an <code>int</code> representing
74 * the default acceptable action(s) to
75 * support, a <code>DropTargetListener</code>
76 * to handle event processing, a <code>boolean</code> indicating
77 * if the <code>DropTarget</code> is currently accepting drops, and
78 * a <code>FlavorMap</code> to use (or null for the default <CODE>FlavorMap</CODE>).
79 * <P>
80 * The Component will receive drops only if it is enabled.
81 * @param c The <code>Component</code> with which this <code>DropTarget</code> is associated
82 * @param ops The default acceptable actions for this <code>DropTarget</code>
83 * @param dtl The <code>DropTargetListener</code> for this <code>DropTarget</code>
84 * @param act Is the <code>DropTarget</code> accepting drops.
85 * @param fm The <code>FlavorMap</code> to use, or null for the default <CODE>FlavorMap</CODE>
86 * @exception HeadlessException if GraphicsEnvironment.isHeadless()
87 * returns true
88 * @see java.awt.GraphicsEnvironment#isHeadless
89 */
90 public DropTarget(Component c, int ops, DropTargetListener dtl,
91 boolean act, FlavorMap fm)
92 throws HeadlessException
93 {
94 if (GraphicsEnvironment.isHeadless()) {
95 throw new HeadlessException();
96 }
97
98 component = c;
99
100 setDefaultActions(ops);
101
102 if (dtl != null) try {
103 addDropTargetListener(dtl);
104 } catch (TooManyListenersException tmle) {
105 // do nothing!
106 }
107
108 if (c != null) {
109 c.setDropTarget(this);
110 setActive(act);
111 }
112
113 if (fm != null) flavorMap = fm;
114 }
115
116 /**
117 * Creates a <code>DropTarget</code> given the <code>Component</code>
118 * to associate itself with, an <code>int</code> representing
119 * the default acceptable action(s)
120 * to support, a <code>DropTargetListener</code>
121 * to handle event processing, and a <code>boolean</code> indicating
122 * if the <code>DropTarget</code> is currently accepting drops.
123 * <P>
124 * The Component will receive drops only if it is enabled.
125 * @param c The <code>Component</code> with which this <code>DropTarget</code> is associated
126 * @param ops The default acceptable actions for this <code>DropTarget</code>
127 * @param dtl The <code>DropTargetListener</code> for this <code>DropTarget</code>
128 * @param act Is the <code>DropTarget</code> accepting drops.
129 * @exception HeadlessException if GraphicsEnvironment.isHeadless()
130 * returns true
131 * @see java.awt.GraphicsEnvironment#isHeadless
132 */
133 public DropTarget(Component c, int ops, DropTargetListener dtl,
134 boolean act)
135 throws HeadlessException
136 {
137 this(c, ops, dtl, act, null);
138 }
139
140 /**
141 * Creates a <code>DropTarget</code>.
142 * @exception HeadlessException if GraphicsEnvironment.isHeadless()
143 * returns true
144 * @see java.awt.GraphicsEnvironment#isHeadless
145 */
146 public DropTarget() throws HeadlessException {
147 this(null, DnDConstants.ACTION_COPY_OR_MOVE, null, true, null);
148 }
149
150 /**
151 * Creates a <code>DropTarget</code> given the <code>Component</code>
152 * to associate itself with, and the <code>DropTargetListener</code>
153 * to handle event processing.
154 * <P>
155 * The Component will receive drops only if it is enabled.
156 * @param c The <code>Component</code> with which this <code>DropTarget</code> is associated
157 * @param dtl The <code>DropTargetListener</code> for this <code>DropTarget</code>
158 * @exception HeadlessException if GraphicsEnvironment.isHeadless()
159 * returns true
160 * @see java.awt.GraphicsEnvironment#isHeadless
161 */
162 public DropTarget(Component c, DropTargetListener dtl)
163 throws HeadlessException
164 {
165 this(c, DnDConstants.ACTION_COPY_OR_MOVE, dtl, true, null);
166 }
167
168 /**
169 * Creates a <code>DropTarget</code> given the <code>Component</code>
170 * to associate itself with, an <code>int</code> representing
171 * the default acceptable action(s) to support, and a
172 * <code>DropTargetListener</code> to handle event processing.
173 * <P>
174 * The Component will receive drops only if it is enabled.
175 * @param c The <code>Component</code> with which this <code>DropTarget</code> is associated
176 * @param ops The default acceptable actions for this <code>DropTarget</code>
177 * @param dtl The <code>DropTargetListener</code> for this <code>DropTarget</code>
178 * @exception HeadlessException if GraphicsEnvironment.isHeadless()
179 * returns true
180 * @see java.awt.GraphicsEnvironment#isHeadless
181 */
182 public DropTarget(Component c, int ops, DropTargetListener dtl)
183 throws HeadlessException
184 {
185 this(c, ops, dtl, true);
186 }
187
188 /**
189 * Note: this interface is required to permit the safe association
190 * of a DropTarget with a Component in one of two ways, either:
191 * <code> component.setDropTarget(droptarget); </code>
192 * or <code> droptarget.setComponent(component); </code>
193 * <P>
194 * The Component will receive drops only if it is enabled.
195 * @param c The new <code>Component</code> this <code>DropTarget</code>
196 * is to be associated with.<P>
197 */
198
199 public synchronized void setComponent(Component c) {
200 if (component == c || component != null && component.equals(c))
201 return;
202
203 Component old;
204 ComponentPeer oldPeer = null;
205
206 if ((old = component) != null) {
207 clearAutoscroll();
208
209 component = null;
210
211 if (componentPeer != null) {
212 oldPeer = componentPeer;
213 removeNotify(componentPeer);
214 }
215
216 old.setDropTarget(null);
217
218 }
219
220 if ((component = c) != null) try {
221 c.setDropTarget(this);
222 } catch (Exception e) { // undo the change
223 if (old != null) {
224 old.setDropTarget(this);
225 addNotify(oldPeer);
226 }
227 }
228 }
229
230 /**
231 * Gets the <code>Component</code> associated
232 * with this <code>DropTarget</code>.
233 * <P>
234 * @return the current <code>Component</code>
235 */
236
237 public synchronized Component getComponent() {
238 return component;
239 }
240
241 /**
242 * Sets the default acceptable actions for this <code>DropTarget</code>
243 * <P>
244 * @param ops the default actions
245 * <P>
246 * @see java.awt.dnd.DnDConstants
247 */
248
249 public void setDefaultActions(int ops) {
250 getDropTargetContext().setTargetActions(ops & (DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_REFERENCE));
251 }
252
253 /*
254 * Called by DropTargetContext.setTargetActions()
255 * with appropriate synchronization.
256 */
257 void doSetDefaultActions(int ops) {
258 actions = ops;
259 }
260
261 /**
262 * Gets an <code>int</code> representing the
263 * current action(s) supported by this <code>DropTarget</code>.
264 * <P>
265 * @return the current default actions
266 */
267
268 public int getDefaultActions() {
269 return actions;
270 }
271
272 /**
273 * Sets the DropTarget active if <code>true</code>,
274 * inactive if <code>false</code>.
275 * <P>
276 * @param isActive sets the <code>DropTarget</code> (in)active.
277 */
278
279 public synchronized void setActive(boolean isActive) {
280 if (isActive != active) {
281 active = isActive;
282 }
283
284 if (!active) clearAutoscroll();
285 }
286
287 /**
288 * Reports whether or not
289 * this <code>DropTarget</code>
290 * is currently active (ready to accept drops).
291 * <P>
292 * @return <CODE>true</CODE> if active, <CODE>false</CODE> if not
293 */
294
295 public boolean isActive() {
296 return active;
297 }
298
299 /**
300 * Adds a new <code>DropTargetListener</code> (UNICAST SOURCE).
301 * <P>
302 * @param dtl The new <code>DropTargetListener</code>
303 * <P>
304 * @throws <code>TooManyListenersException</code> if a
305 * <code>DropTargetListener</code> is already added to this
306 * <code>DropTarget</code>.
307 */
308
309 public synchronized void addDropTargetListener(DropTargetListener dtl) throws TooManyListenersException {
310 if (dtl == null) return;
311
312 if (equals(dtl)) throw new IllegalArgumentException("DropTarget may not be its own Listener");
313
314 if (dtListener == null)
315 dtListener = dtl;
316 else
317 throw new TooManyListenersException();
318 }
319
320 /**
321 * Removes the current <code>DropTargetListener</code> (UNICAST SOURCE).
322 * <P>
323 * @param dtl the DropTargetListener to deregister.
324 */
325
326 public synchronized void removeDropTargetListener(DropTargetListener dtl) {
327 if (dtl != null && dtListener != null) {
328 if(dtListener.equals(dtl))
329 dtListener = null;
330 else
331 throw new IllegalArgumentException("listener mismatch");
332 }
333 }
334
335 /**
336 * Calls <code>dragEnter</code> on the registered
337 * <code>DropTargetListener</code> and passes it
338 * the specified <code>DropTargetDragEvent</code>.
339 * Has no effect if this <code>DropTarget</code>
340 * is not active.
341 *
342 * @param dtde the <code>DropTargetDragEvent</code>
343 *
344 * @throws NullPointerException if this <code>DropTarget</code>
345 * is active and <code>dtde</code> is <code>null</code>
346 *
347 * @see #isActive
348 */
349 public synchronized void dragEnter(DropTargetDragEvent dtde) {
350 if (!active) return;
351
352 if (dtListener != null) {
353 dtListener.dragEnter(dtde);
354 } else
355 dtde.getDropTargetContext().setTargetActions(DnDConstants.ACTION_NONE);
356
357 initializeAutoscrolling(dtde.getLocation());
358 }
359
360 /**
361 * Calls <code>dragOver</code> on the registered
362 * <code>DropTargetListener</code> and passes it
363 * the specified <code>DropTargetDragEvent</code>.
364 * Has no effect if this <code>DropTarget</code>
365 * is not active.
366 *
367 * @param dtde the <code>DropTargetDragEvent</code>
368 *
369 * @throws NullPointerException if this <code>DropTarget</code>
370 * is active and <code>dtde</code> is <code>null</code>
371 *
372 * @see #isActive
373 */
374 public synchronized void dragOver(DropTargetDragEvent dtde) {
375 if (!active) return;
376
377 if (dtListener != null && active) dtListener.dragOver(dtde);
378
379 updateAutoscroll(dtde.getLocation());
380 }
381
382 /**
383 * Calls <code>dropActionChanged</code> on the registered
384 * <code>DropTargetListener</code> and passes it
385 * the specified <code>DropTargetDragEvent</code>.
386 * Has no effect if this <code>DropTarget</code>
387 * is not active.
388 *
389 * @param dtde the <code>DropTargetDragEvent</code>
390 *
391 * @throws NullPointerException if this <code>DropTarget</code>
392 * is active and <code>dtde</code> is <code>null</code>
393 *
394 * @see #isActive
395 */
396 public synchronized void dropActionChanged(DropTargetDragEvent dtde) {
397 if (!active) return;
398
399 if (dtListener != null) dtListener.dropActionChanged(dtde);
400
401 updateAutoscroll(dtde.getLocation());
402 }
403
404 /**
405 * Calls <code>dragExit</code> on the registered
406 * <code>DropTargetListener</code> and passes it
407 * the specified <code>DropTargetEvent</code>.
408 * Has no effect if this <code>DropTarget</code>
409 * is not active.
410 * <p>
411 * This method itself does not throw any exception
412 * for null parameter but for exceptions thrown by
413 * the respective method of the listener.
414 *
415 * @param dte the <code>DropTargetEvent</code>
416 *
417 * @see #isActive
418 */
419 public synchronized void dragExit(DropTargetEvent dte) {
420 if (!active) return;
421
422 if (dtListener != null && active) dtListener.dragExit(dte);
423
424 clearAutoscroll();
425 }
426
427 /**
428 * Calls <code>drop</code> on the registered
429 * <code>DropTargetListener</code> and passes it
430 * the specified <code>DropTargetDropEvent</code>
431 * if this <code>DropTarget</code> is active.
432 *
433 * @param dtde the <code>DropTargetDropEvent</code>
434 *
435 * @throws NullPointerException if <code>dtde</code> is null
436 * and at least one of the following is true: this
437 * <code>DropTarget</code> is not active, or there is
438 * no a <code>DropTargetListener</code> registered.
439 *
440 * @see #isActive
441 */
442 public synchronized void drop(DropTargetDropEvent dtde) {
443 clearAutoscroll();
444
445 if (dtListener != null && active)
446 dtListener.drop(dtde);
447 else { // we should'nt get here ...
448 dtde.rejectDrop();
449 }
450 }
451
452 /**
453 * Gets the <code>FlavorMap</code>
454 * associated with this <code>DropTarget</code>.
455 * If no <code>FlavorMap</code> has been set for this
456 * <code>DropTarget</code>, it is associated with the default
457 * <code>FlavorMap</code>.
458 * <P>
459 * @return the FlavorMap for this DropTarget
460 */
461
462 public FlavorMap getFlavorMap() { return flavorMap; }
463
464 /**
465 * Sets the <code>FlavorMap</code> associated
466 * with this <code>DropTarget</code>.
467 * <P>
468 * @param fm the new <code>FlavorMap</code>, or null to
469 * associate the default FlavorMap with this DropTarget.
470 */
471
472 public void setFlavorMap(FlavorMap fm) {
473 flavorMap = fm == null ? SystemFlavorMap.getDefaultFlavorMap() : fm;
474 }
475
476 /**
477 * Notify the DropTarget that it has been associated with a Component
478 *
479 **********************************************************************
480 * This method is usually called from java.awt.Component.addNotify() of
481 * the Component associated with this DropTarget to notify the DropTarget
482 * that a ComponentPeer has been associated with that Component.
483 *
484 * Calling this method, other than to notify this DropTarget of the
485 * association of the ComponentPeer with the Component may result in
486 * a malfunction of the DnD system.
487 **********************************************************************
488 * <P>
489 * @param peer The Peer of the Component we are associated with!
490 *
491 */
492
493 public void addNotify(ComponentPeer peer) {
494 if (peer == componentPeer) return;
495
496 componentPeer = peer;
497
498 for (Component c = component;
499 c != null && peer instanceof LightweightPeer; c = c.getParent()) {
500 peer = c.getPeer();
501 }
502
503 if (peer instanceof DropTargetPeer) {
504 nativePeer = peer;
505 ((DropTargetPeer)peer).addDropTarget(this);
506 } else {
507 nativePeer = null;
508 }
509 }
510
511 /**
512 * Notify the DropTarget that it has been disassociated from a Component
513 *
514 **********************************************************************
515 * This method is usually called from java.awt.Component.removeNotify() of
516 * the Component associated with this DropTarget to notify the DropTarget
517 * that a ComponentPeer has been disassociated with that Component.
518 *
519 * Calling this method, other than to notify this DropTarget of the
520 * disassociation of the ComponentPeer from the Component may result in
521 * a malfunction of the DnD system.
522 **********************************************************************
523 * <P>
524 * @param peer The Peer of the Component we are being disassociated from!
525 */
526
527 public void removeNotify(ComponentPeer peer) {
528 if (nativePeer != null)
529 ((DropTargetPeer)nativePeer).removeDropTarget(this);
530
531 componentPeer = nativePeer = null;
532 }
533
534 /**
535 * Gets the <code>DropTargetContext</code> associated
536 * with this <code>DropTarget</code>.
537 * <P>
538 * @return the <code>DropTargetContext</code> associated with this <code>DropTarget</code>.
539 */
540
541 public DropTargetContext getDropTargetContext() {
542 return dropTargetContext;
543 }
544
545 /**
546 * Creates the DropTargetContext associated with this DropTarget.
547 * Subclasses may override this method to instantiate their own
548 * DropTargetContext subclass.
549 *
550 * This call is typically *only* called by the platform's
551 * DropTargetContextPeer as a drag operation encounters this
552 * DropTarget. Accessing the Context while no Drag is current
553 * has undefined results.
554 */
555
556 protected DropTargetContext createDropTargetContext() {
557 return new DropTargetContext(this);
558 }
559
560 /**
561 * Serializes this <code>DropTarget</code>. Performs default serialization,
562 * and then writes out this object's <code>DropTargetListener</code> if and
563 * only if it can be serialized. If not, <code>null</code> is written
564 * instead.
565 *
566 * @serialData The default serializable fields, in alphabetical order,
567 * followed by either a <code>DropTargetListener</code>
568 * instance, or <code>null</code>.
569 * @since 1.4
570 */
571 private void writeObject(ObjectOutputStream s) throws IOException {
572 s.defaultWriteObject();
573
574 s.writeObject(SerializationTester.test(dtListener)
575 ? dtListener : null);
576 }
577
578 /**
579 * Deserializes this <code>DropTarget</code>. This method first performs
580 * default deserialization for all non-<code>transient</code> fields. An
581 * attempt is then made to deserialize this object's
582 * <code>DropTargetListener</code> as well. This is first attempted by
583 * deserializing the field <code>dtListener</code>, because, in releases
584 * prior to 1.4, a non-<code>transient</code> field of this name stored the
585 * <code>DropTargetListener</code>. If this fails, the next object in the
586 * stream is used instead.
587 *
588 * @since 1.4
589 */
590 private void readObject(ObjectInputStream s)
591 throws ClassNotFoundException, IOException
592 {
593 ObjectInputStream.GetField f = s.readFields();
594
595 try {
596 dropTargetContext =
597 (DropTargetContext)f.get("dropTargetContext", null);
598 } catch (IllegalArgumentException e) {
599 // Pre-1.4 support. 'dropTargetContext' was previoulsy transient
600 }
601 if (dropTargetContext == null) {
602 dropTargetContext = createDropTargetContext();
603 }
604
605 component = (Component)f.get("component", null);
606 actions = f.get("actions", DnDConstants.ACTION_COPY_OR_MOVE);
607 active = f.get("active", true);
608
609 // Pre-1.4 support. 'dtListener' was previously non-transient
610 try {
611 dtListener = (DropTargetListener)f.get("dtListener", null);
612 } catch (IllegalArgumentException e) {
613 // 1.4-compatible byte stream. 'dtListener' was written explicitly
614 dtListener = (DropTargetListener)s.readObject();
615 }
616 }
617
618 /*********************************************************************/
619
620 /**
621 * this protected nested class implements autoscrolling
622 */
623
624 protected static class DropTargetAutoScroller implements ActionListener {
625
626 /**
627 * construct a DropTargetAutoScroller
628 * <P>
629 * @param c the <code>Component</code>
630 * @param p the <code>Point</code>
631 */
632
633 protected DropTargetAutoScroller(Component c, Point p) {
634 super();
635
636 component = c;
637 autoScroll = (Autoscroll)component;
638
639 Toolkit t = Toolkit.getDefaultToolkit();
640
641 Integer initial = Integer.valueOf(100);
642 Integer interval = Integer.valueOf(100);
643
644 try {
645 initial = (Integer)t.getDesktopProperty("DnD.Autoscroll.initialDelay");
646 } catch (Exception e) {
647 // ignore
648 }
649
650 try {
651 interval = (Integer)t.getDesktopProperty("DnD.Autoscroll.interval");
652 } catch (Exception e) {
653 // ignore
654 }
655
656 timer = new Timer(interval.intValue(), this);
657
658 timer.setCoalesce(true);
659 timer.setInitialDelay(initial.intValue());
660
661 locn = p;
662 prev = p;
663
664 try {
665 hysteresis = ((Integer)t.getDesktopProperty("DnD.Autoscroll.cursorHysteresis")).intValue();
666 } catch (Exception e) {
667 // ignore
668 }
669
670 timer.start();
671 }
672
673 /**
674 * update the geometry of the autoscroll region
675 */
676
677 private void updateRegion() {
678 Insets i = autoScroll.getAutoscrollInsets();
679 Dimension size = component.getSize();
680
681 if (size.width != outer.width || size.height != outer.height)
682 outer.reshape(0, 0, size.width, size.height);
683
684 if (inner.x != i.left || inner.y != i.top)
685 inner.setLocation(i.left, i.top);
686
687 int newWidth = size.width - (i.left + i.right);
688 int newHeight = size.height - (i.top + i.bottom);
689
690 if (newWidth != inner.width || newHeight != inner.height)
691 inner.setSize(newWidth, newHeight);
692
693 }
694
695 /**
696 * cause autoscroll to occur
697 * <P>
698 * @param newLocn the <code>Point</code>
699 */
700
701 protected synchronized void updateLocation(Point newLocn) {
702 prev = locn;
703 locn = newLocn;
704
705 if (Math.abs(locn.x - prev.x) > hysteresis ||
706 Math.abs(locn.y - prev.y) > hysteresis) {
707 if (timer.isRunning()) timer.stop();
708 } else {
709 if (!timer.isRunning()) timer.start();
710 }
711 }
712
713 /**
714 * cause autoscrolling to stop
715 */
716
717 protected void stop() { timer.stop(); }
718
719 /**
720 * cause autoscroll to occur
721 * <P>
722 * @param e the <code>ActionEvent</code>
723 */
724
725 public synchronized void actionPerformed(ActionEvent e) {
726 updateRegion();
727
728 if (outer.contains(locn) && !inner.contains(locn))
729 autoScroll.autoscroll(locn);
730 }
731
732 /*
733 * fields
734 */
735
736 private Component component;
737 private Autoscroll autoScroll;
738
739 private Timer timer;
740
741 private Point locn;
742 private Point prev;
743
744 private Rectangle outer = new Rectangle();
745 private Rectangle inner = new Rectangle();
746
747 private int hysteresis = 10;
748 }
749
750 /*********************************************************************/
751
752 /**
753 * create an embedded autoscroller
754 * <P>
755 * @param c the <code>Component</code>
756 * @param p the <code>Point</code>
757 */
758
759 protected DropTargetAutoScroller createDropTargetAutoScroller(Component c, Point p) {
760 return new DropTargetAutoScroller(c, p);
761 }
762
763 /**
764 * initialize autoscrolling
765 * <P>
766 * @param p the <code>Point</code>
767 */
768
769 protected void initializeAutoscrolling(Point p) {
770 if (component == null || !(component instanceof Autoscroll)) return;
771
772 autoScroller = createDropTargetAutoScroller(component, p);
773 }
774
775 /**
776 * update autoscrolling with current cursor locn
777 * <P>
778 * @param dragCursorLocn the <code>Point</code>
779 */
780
781 protected void updateAutoscroll(Point dragCursorLocn) {
782 if (autoScroller != null) autoScroller.updateLocation(dragCursorLocn);
783 }
784
785 /**
786 * clear autoscrolling
787 */
788
789 protected void clearAutoscroll() {
790 if (autoScroller != null) {
791 autoScroller.stop();
792 autoScroller = null;
793 }
794 }
795
796 /**
797 * The DropTargetContext associated with this DropTarget.
798 *
799 * @serial
800 */
801 private DropTargetContext dropTargetContext = createDropTargetContext();
802
803 /**
804 * The Component associated with this DropTarget.
805 *
806 * @serial
807 */
808 private Component component;
809
810 /*
811 * That Component's Peer
812 */
813 private transient ComponentPeer componentPeer;
814
815 /*
816 * That Component's "native" Peer
817 */
818 private transient ComponentPeer nativePeer;
819
820
821 /**
822 * Default permissible actions supported by this DropTarget.
823 *
824 * @see #setDefaultActions
825 * @see #getDefaultActions
826 * @serial
827 */
828 int actions = DnDConstants.ACTION_COPY_OR_MOVE;
829
830 /**
831 * <code>true</code> if the DropTarget is accepting Drag & Drop operations.
832 *
833 * @serial
834 */
835 boolean active = true;
836
837 /*
838 * the auto scrolling object
839 */
840
841 private transient DropTargetAutoScroller autoScroller;
842
843 /*
844 * The delegate
845 */
846
847 private transient DropTargetListener dtListener;
848
849 /*
850 * The FlavorMap
851 */
852
853 private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap();
854}