Home » openjdk-7 » java » awt » dnd » [javadoc | source]

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

Home » openjdk-7 » java » awt » dnd » [javadoc | source]