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