home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / awt / dnd / DropTarget.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  12.7 KB  |  514 lines

  1. /*
  2.  * @(#)DropTarget.java    1.16 98/03/18
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.awt.dnd;
  16.  
  17. import java.util.TooManyListenersException;
  18.  
  19. import java.io.Serializable;
  20.  
  21. import java.awt.AWTEvent;
  22. import java.awt.AWTPermission;
  23. import java.awt.Component;
  24. import java.awt.Dimension;
  25. import java.awt.Insets;
  26. import java.awt.Point;
  27. import java.awt.Rectangle;
  28. import java.awt.Toolkit;
  29.  
  30. import java.awt.event.ActionEvent;
  31. import java.awt.event.ActionListener;
  32.  
  33. import java.awt.dnd.DnDConstants;
  34. import java.awt.dnd.DropTargetContext;
  35. import java.awt.dnd.DropTargetDragEvent;
  36. import java.awt.dnd.DropTargetDropEvent;
  37. import java.awt.dnd.DropTargetListener;
  38. import java.awt.dnd.FlavorMap;
  39. import java.awt.dnd.SystemFlavorMap;
  40. import java.awt.dnd.Autoscroll;
  41.  
  42. import java.awt.peer.ComponentPeer;
  43. import java.awt.peer.LightweightPeer;
  44.  
  45. import java.awt.dnd.peer.DropTargetPeer;
  46.  
  47. import java.security.AccessController;
  48.  
  49. /**
  50.  * <p>
  51.  * The DropTarget is associated with a Component, when that Component wishes
  52.  * to accept Drops during Drag and Drop operations. 
  53.  * </p>
  54.  *
  55.  * @version 1.16
  56.  * @since JDK1.2
  57.  *
  58.  */
  59.  
  60. public class DropTarget implements DropTargetListener, Serializable {
  61.  
  62.     static final long serialVersionUID = -6283860791671019047L;
  63.  
  64.     /*
  65.      * default FlavorMap for the system
  66.      */
  67.  
  68.     static private final FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap();
  69.  
  70.     /**
  71.      * Construct a DropTarget
  72.      *
  73.      * @param c     The Component with which this DropTarget is associated
  74.      * @param ops    The default acceptable actions for this DropTarget
  75.      * @param dtl    The DropTargetListener for this DropTarget
  76.      * @param act    Is the DropTarget accepting drops.
  77.      *
  78.      * @throw java.lang.SecurityException
  79.      */
  80.  
  81.     public DropTarget(Component c, int ops, DropTargetListener dtl, boolean act) {
  82.     super();
  83.  
  84.     setDefaultActions(ops);
  85.  
  86.     if (dtl != null) try {
  87.         addDropTargetListener(dtl);
  88.     } catch (TooManyListenersException tmle) {
  89.         // do nothing!
  90.     }
  91.  
  92.     if (c != null) c.setDropTarget(this);
  93.  
  94.     setActive(act);
  95.     }
  96.  
  97.     /**
  98.      * Construct a DropTarget
  99.      *
  100.      * @throw java.lang.SecurityException
  101.      */
  102.  
  103.     public DropTarget() throws SecurityException {
  104.     this(null, DnDConstants.ACTION_COPY_OR_MOVE, null, true);
  105.     }
  106.  
  107.     /**
  108.      * Construct a DropTarget
  109.      *
  110.      * @param c     The Component with which this DropTarget is associated
  111.      * @param dtl    The DropTargetListener for this DropTarget
  112.      *
  113.      * @throw java.lang.SecurityException
  114.      */
  115.  
  116.     public DropTarget(Component c, DropTargetListener dtl) throws SecurityException {
  117.     this(c, DnDConstants.ACTION_COPY_OR_MOVE, dtl, true);
  118.     }
  119.  
  120.     /**
  121.      * Construct a DropTarget
  122.      *
  123.      * @param c     The Component with which this DropTarget is associated
  124.      * @param ops    The default acceptable actions for this DropTarget
  125.      * @param dtl    The DropTargetListener for this DropTarget
  126.      *
  127.      * @throw java.lang.SecurityException
  128.      */
  129.  
  130.     public DropTarget(Component c, int ops, DropTargetListener dtl) throws SecurityException {
  131.     this(c, ops, dtl, true);
  132.     }
  133.  
  134.     /**
  135.      * Note: this interface is required to permit the safe association
  136.      * of a DropTarget with a Component in one of two ways, either:
  137.      * <code> component.setDropTarget(droptarget); </code>
  138.      * or <code> droptarget.setComponent(component); </code>
  139.      *
  140.      * The caller must have AWTPermission.setDropTarget to succeed.
  141.      *
  142.      * @param c The new Component this DropTarget is to be associated with.
  143.      *
  144.      * @throw SecurityException
  145.      * @throw IllegalArgumentException
  146.      * @throw UnsupportedOperationException
  147.      */
  148.  
  149.     public synchronized void setComponent(Component c) {
  150.     if (component == c || component != null && component.equals(c))
  151.         return;
  152.     
  153.  
  154.     /*
  155.       * FIX THIS FOR BETA4
  156.      */
  157.  
  158.     // java.security.AccessController.checkPermission(new AWTPermission("setDropTarget"));
  159.  
  160.     Component     old;
  161.     ComponentPeer oldPeer = null;
  162.  
  163.     if ((old = component) != null) {
  164.         clearAutoscroll();
  165.  
  166.         component = null;
  167.  
  168.         if (componentPeer != null) {
  169.         oldPeer = componentPeer;
  170.         removeNotify(componentPeer);
  171.         }
  172.  
  173.         old.setDropTarget(null); 
  174.  
  175.     }
  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.     /**
  188.      * @return the current Component
  189.      */
  190.  
  191.     public synchronized Component getComponent() {
  192.     return component;
  193.     }
  194.  
  195.     /**
  196.      * Sets the default acceptable actions for this DropTarget
  197.      *
  198.      * @param ops the default actions.
  199.      *
  200.      * @see java.awt.dnd.DnDConstants
  201.      */
  202.  
  203.     public synchronized void setDefaultActions(int ops) {
  204.     actions = ops & (DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_REFERENCE);
  205.  
  206.     if (dropTargetContext != null) dropTargetContext.setTargetActions(actions);
  207.  
  208.     }
  209.  
  210.     /**
  211.      * @return the current default actions
  212.      */
  213.  
  214.     public synchronized int getDefaultActions() {
  215.     return actions;
  216.     }
  217.  
  218.     /**
  219.      * set the DropTarget (in)active.
  220.      *
  221.      * @param isActive
  222.      */
  223.  
  224.     public synchronized void setActive(boolean isActive) {
  225.     if (isActive != active) {
  226.         active = isActive;
  227.     }
  228.  
  229.     if (!active) clearAutoscroll();
  230.     }
  231.  
  232.     /**
  233.      * @return is the DropTarget active?
  234.      */
  235.  
  236.     public synchronized boolean isActive() {
  237.     return active;
  238.     }
  239.  
  240.     /**
  241.      * Add a new DropTargetListener (UNICAST SOURCE)
  242.      *
  243.      * @param dte The new DropTargetListener
  244.      *
  245.      * @throw TooManyListenersExceptio
  246.      */
  247.  
  248.     public synchronized void addDropTargetListener(DropTargetListener dte) throws TooManyListenersException {
  249.     if (dte == null) return;
  250.  
  251.     if (dtListener == null)
  252.         dtListener = dte;
  253.     else
  254.         throw new TooManyListenersException();
  255.     }
  256.  
  257.     /**
  258.      * Remove the current DropTargetListener (UNICAST SOURCE)
  259.      *
  260.      * @param dte the DropTargetListener to deregister.
  261.      *
  262.      * @throw IllegalArgumentException
  263.      */
  264.  
  265.     public synchronized void removeDropTargetListener(DropTargetListener dte) {
  266.     if (dte != null && dtListener != null) {
  267.         if(dtListener.equals(dte))
  268.         dtListener = null;
  269.         else
  270.         throw new IllegalArgumentException();
  271.     }
  272.     }
  273.  
  274.  
  275.     /**
  276.      * The DropTarget intercepts dragEnter() notifications before the 
  277.      * registered DropTargetListener gets them. 
  278.      */
  279.  
  280.     public synchronized void dragEnter(DropTargetDragEvent dtde) {
  281.     if (!active) return;
  282.  
  283.     if (dtListener != null) {
  284.         dtListener.dragEnter(dtde);
  285.     } else
  286.             dtde.getDropTargetContext().setTargetActions(DnDConstants.ACTION_NONE);
  287.  
  288.     initializeAutoscrolling(dtde.getLocation());
  289.     }
  290.  
  291.     /**
  292.      * The DropTarget intercepts dragOver() notifications before the
  293.      * registered DropTargetListener gets them.
  294.      */
  295.  
  296.     public synchronized void dragOver(DropTargetDragEvent dtde) {
  297.     if (!active) return;
  298.  
  299.     if (dtListener != null && active) dtListener.dragOver(dtde);
  300.  
  301.     updateAutoscroll(dtde.getLocation());
  302.     }
  303.  
  304.     /**
  305.      * The DropTarget intercepts dropActionChanged() notifications before the 
  306.      * registered DropTargetListener gets them.
  307.      */
  308.  
  309.     public void dropActionChanged(DropTargetDragEvent dtde) {
  310.     if (!active) return;
  311.  
  312.     if (dtListener != null) dtListener.dropActionChanged(dtde);
  313.  
  314.     updateAutoscroll(dtde.getLocation());
  315.     }
  316.  
  317.     /**
  318.      * The DropTarget intercepts dragExit() notifications before the 
  319.      * registered DropTargetListener gets them.
  320.      */
  321.  
  322.     public synchronized void dragExit(DropTargetEvent dte) {
  323.     if (!active) return;
  324.  
  325.     if (dtListener != null && active) dtListener.dragExit(dte);
  326.  
  327.     clearAutoscroll();
  328.     }
  329.  
  330.     /**
  331.      * The DropTarget intercepts drop() notifications before the 
  332.      * registered DropTargetListener gets them.
  333.      */
  334.  
  335.     public synchronized void drop(DropTargetDropEvent dtde) {
  336.     if (dtListener != null && active)
  337.         dtListener.drop(dtde);
  338.     else { // we should'nt get here ...
  339.         dtde.rejectDrop();
  340.     }
  341.     }
  342.  
  343.     /**
  344.      * @return the FlavorMap for this DropTarget
  345.      */
  346.  
  347.     public FlavorMap getFlavorMap() { return flavorMap; }
  348.  
  349.     /**
  350.      * Notify the DropTarget that it has been associated with a Component
  351.      *
  352.      **********************************************************************
  353.      * This method is usually called from java.awt.Component.addNotify() of
  354.      * the Component associated with this DropTarget to notify the DropTarget
  355.      * that a ComponentPeer has been associated with that Component.
  356.      *
  357.      * Calling this method, other than to notify this DropTarget of the
  358.      * association of the ComponentPeer with the Component may result in
  359.      * a malfunction of the DnD system.
  360.      **********************************************************************
  361.      *
  362.      * @param peer The Peer of the Component we are associated with!
  363.      *
  364.      * @throw SecurityException
  365.      */
  366.  
  367.     public void addNotify(ComponentPeer peer) throws SecurityException {
  368.     /*
  369.      * FIX THIS FOR BETA4
  370.      */
  371.  
  372.     // java.security.AccessController.checkPermission(new AWTPermission("setDTarget"));
  373.     if (peer == componentPeer) return;
  374.  
  375.     componentPeer = peer;
  376.  
  377.     for (Component c = component; peer instanceof LightweightPeer; c = c.getParent())
  378.         peer = c.getPeer();
  379.          
  380.     try {
  381.         ((DropTargetPeer)(nativePeer = peer)).addDropTarget(this);
  382.     } catch (ClassCastException cce) {
  383.         nativePeer = null;
  384.         // throw new InvalidDnDOperationException("No Native Peer support");
  385.     }
  386.     }
  387.  
  388.     /**
  389.      * Notify the DropTarget that it has been disassociated from a Component
  390.      *
  391.      **********************************************************************
  392.      * This method is usually called from java.awt.Component.removeNotify() of
  393.      * the Component associated with this DropTarget to notify the DropTarget
  394.      * that a ComponentPeer has been disassociated with that Component.
  395.      *
  396.      * Calling this method, other than to notify this DropTarget of the
  397.      * disassociation of the ComponentPeer from the Component may result in
  398.      * a malfunction of the DnD system.
  399.      **********************************************************************
  400.      *
  401.      * @param peer The Peer of the Component we are being disassociated froe!
  402.      */
  403.  
  404.     public void removeNotify(ComponentPeer peer) {
  405.     if (nativePeer != null)
  406.         ((DropTargetPeer)nativePeer).removeDropTarget(this);
  407.  
  408.     componentPeer = nativePeer = null;
  409.     }
  410.  
  411.     /**
  412.      * @return the DropTargetContext associated with this DropTarget.
  413.      */
  414.  
  415.     public DropTargetContext getDropTargetContext() {
  416.     if (dropTargetContext == null) dropTargetContext = createDropTargetContext();
  417.  
  418.     return dropTargetContext;
  419.     }
  420.  
  421.     /**
  422.      * Create the DropTargetContext associated with this DropTarget.
  423.      * Subclasses may override this method to instantiate their own
  424.      * DropTargetContext subclass.
  425.      *
  426.      * This call is typically *only* called by the platform's
  427.      * DropTargetContextPeer as a drag operation encounters this
  428.      * DropTarget. Accessing the Context while no Drag is current
  429.      * has undefined results.
  430.      *
  431.      * @param owner the owner of the DropTargetContext
  432.      */
  433.  
  434.     protected DropTargetContext createDropTargetContext() {
  435.     return new DropTargetContext(this);
  436.     }
  437.  
  438.     /*********************************************************************/
  439.  
  440.     /*********************************************************************/
  441.  
  442.     /**
  443.      * initialize autoscrolling
  444.      */
  445.  
  446.     protected void initializeAutoscrolling(Point p) {
  447.     if (component == null || !(component instanceof Autoscroll)) return;
  448.  
  449.     // TODO
  450.     }
  451.  
  452.     /**
  453.      * update autoscrolling with current cursor locn
  454.      */
  455.  
  456.     protected void updateAutoscroll(Point dragCursorLocn) {
  457.     // TODO
  458.     }
  459.  
  460.     /**
  461.      * clear autoscrolling
  462.      */
  463.  
  464.     protected void clearAutoscroll() {
  465.     // TODO
  466.     }
  467.  
  468.     /**
  469.      * The DropTargetContext associated with this DropTarget
  470.      */
  471.  
  472.     private transient DropTargetContext dropTargetContext;
  473.  
  474.     /**
  475.      * The Component associated with this DropTarget
  476.      */
  477.  
  478.     private Component component;
  479.  
  480.     /**
  481.      * That Component's  Peer
  482.      */
  483.  
  484.     private transient ComponentPeer componentPeer;
  485.  
  486.     /**
  487.      * That Component's "native" Peer
  488.      */
  489.  
  490.     private transient ComponentPeer nativePeer;
  491.  
  492.  
  493.     /**
  494.      * Default permissable actions supported by this DropTarget
  495.      *
  496.      * @see #setDefaultActions
  497.      * @see #getDefaultActions
  498.      */
  499.  
  500.     int        actions = DnDConstants.ACTION_COPY_OR_MOVE;
  501.  
  502.     /**
  503.      * Is the Target accepting DND ops ...
  504.      */
  505.  
  506.     boolean active = true;
  507.  
  508.     /**
  509.      * The delegate
  510.      */
  511.  
  512.     private DropTargetListener dtListener;
  513. }
  514.