|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package java.awt.dnd; |
|
|
|
import java.awt.Component; |
|
|
|
import java.awt.datatransfer.DataFlavor; |
|
import java.awt.datatransfer.Transferable; |
|
import java.awt.datatransfer.UnsupportedFlavorException; |
|
|
|
import java.awt.dnd.peer.DropTargetContextPeer; |
|
|
|
import java.io.IOException; |
|
import java.io.Serializable; |
|
|
|
import java.util.Arrays; |
|
import java.util.List; |
|
|
|
|
|
/** |
|
* A <code>DropTargetContext</code> is created |
|
* whenever the logical cursor associated |
|
* with a Drag and Drop operation coincides with the visible geometry of |
|
* a <code>Component</code> associated with a <code>DropTarget</code>. |
|
* The <code>DropTargetContext</code> provides |
|
* the mechanism for a potential receiver |
|
* of a drop operation to both provide the end user with the appropriate |
|
* drag under feedback, but also to effect the subsequent data transfer |
|
* if appropriate. |
|
* |
|
* @since 1.2 |
|
*/ |
|
|
|
public class DropTargetContext implements Serializable { |
|
|
|
private static final long serialVersionUID = -634158968993743371L; |
|
|
|
/** |
|
* Construct a <code>DropTargetContext</code> |
|
* given a specified <code>DropTarget</code>. |
|
* <P> |
|
* @param dt the DropTarget to associate with |
|
*/ |
|
|
|
DropTargetContext(DropTarget dt) { |
|
super(); |
|
|
|
dropTarget = dt; |
|
} |
|
|
|
/** |
|
* This method returns the <code>DropTarget</code> associated with this |
|
* <code>DropTargetContext</code>. |
|
* <P> |
|
* @return the <code>DropTarget</code> associated with this <code>DropTargetContext</code> |
|
*/ |
|
|
|
public DropTarget getDropTarget() { return dropTarget; } |
|
|
|
/** |
|
* This method returns the <code>Component</code> associated with |
|
* this <code>DropTargetContext</code>. |
|
* <P> |
|
* @return the Component associated with this Context |
|
*/ |
|
|
|
public Component getComponent() { return dropTarget.getComponent(); } |
|
|
|
/** |
|
* Called when associated with the <code>DropTargetContextPeer</code>. |
|
* <P> |
|
* @param dtcp the <code>DropTargetContextPeer</code> |
|
*/ |
|
|
|
public void addNotify(DropTargetContextPeer dtcp) { |
|
dropTargetContextPeer = dtcp; |
|
} |
|
|
|
/** |
|
* Called when disassociated with the <code>DropTargetContextPeer</code>. |
|
*/ |
|
|
|
public void removeNotify() { |
|
dropTargetContextPeer = null; |
|
transferable = null; |
|
} |
|
|
|
/** |
|
* This method sets the current actions acceptable to |
|
* this <code>DropTarget</code>. |
|
* <P> |
|
* @param actions an <code>int</code> representing the supported action(s) |
|
*/ |
|
|
|
protected void setTargetActions(int actions) { |
|
DropTargetContextPeer peer = getDropTargetContextPeer(); |
|
if (peer != null) { |
|
synchronized (peer) { |
|
peer.setTargetActions(actions); |
|
getDropTarget().doSetDefaultActions(actions); |
|
} |
|
} else { |
|
getDropTarget().doSetDefaultActions(actions); |
|
} |
|
} |
|
|
|
/** |
|
* This method returns an <code>int</code> representing the |
|
* current actions this <code>DropTarget</code> will accept. |
|
* <P> |
|
* @return the current actions acceptable to this <code>DropTarget</code> |
|
*/ |
|
|
|
protected int getTargetActions() { |
|
DropTargetContextPeer peer = getDropTargetContextPeer(); |
|
return ((peer != null) |
|
? peer.getTargetActions() |
|
: dropTarget.getDefaultActions() |
|
); |
|
} |
|
|
|
/** |
|
* This method signals that the drop is completed and |
|
* if it was successful or not. |
|
* <P> |
|
* @param success true for success, false if not |
|
* <P> |
|
* @throws InvalidDnDOperationException if a drop is not outstanding/extant |
|
*/ |
|
|
|
public void dropComplete(boolean success) throws InvalidDnDOperationException{ |
|
DropTargetContextPeer peer = getDropTargetContextPeer(); |
|
if (peer != null) { |
|
peer.dropComplete(success); |
|
} |
|
} |
|
|
|
/** |
|
* accept the Drag. |
|
* <P> |
|
* @param dragOperation the supported action(s) |
|
*/ |
|
|
|
protected void acceptDrag(int dragOperation) { |
|
DropTargetContextPeer peer = getDropTargetContextPeer(); |
|
if (peer != null) { |
|
peer.acceptDrag(dragOperation); |
|
} |
|
} |
|
|
|
/** |
|
* reject the Drag. |
|
*/ |
|
|
|
protected void rejectDrag() { |
|
DropTargetContextPeer peer = getDropTargetContextPeer(); |
|
if (peer != null) { |
|
peer.rejectDrag(); |
|
} |
|
} |
|
|
|
/** |
|
* called to signal that the drop is acceptable |
|
* using the specified operation. |
|
* must be called during DropTargetListener.drop method invocation. |
|
* <P> |
|
* @param dropOperation the supported action(s) |
|
*/ |
|
|
|
protected void acceptDrop(int dropOperation) { |
|
DropTargetContextPeer peer = getDropTargetContextPeer(); |
|
if (peer != null) { |
|
peer.acceptDrop(dropOperation); |
|
} |
|
} |
|
|
|
/** |
|
* called to signal that the drop is unacceptable. |
|
* must be called during DropTargetListener.drop method invocation. |
|
*/ |
|
|
|
protected void rejectDrop() { |
|
DropTargetContextPeer peer = getDropTargetContextPeer(); |
|
if (peer != null) { |
|
peer.rejectDrop(); |
|
} |
|
} |
|
|
|
/** |
|
* get the available DataFlavors of the |
|
* <code>Transferable</code> operand of this operation. |
|
* <P> |
|
* @return a <code>DataFlavor[]</code> containing the |
|
* supported <code>DataFlavor</code>s of the |
|
* <code>Transferable</code> operand. |
|
*/ |
|
|
|
protected DataFlavor[] getCurrentDataFlavors() { |
|
DropTargetContextPeer peer = getDropTargetContextPeer(); |
|
return peer != null ? peer.getTransferDataFlavors() : new DataFlavor[0]; |
|
} |
|
|
|
/** |
|
* This method returns a the currently available DataFlavors |
|
* of the <code>Transferable</code> operand |
|
* as a <code>java.util.List</code>. |
|
* <P> |
|
* @return the currently available |
|
* DataFlavors as a <code>java.util.List</code> |
|
*/ |
|
|
|
protected List<DataFlavor> getCurrentDataFlavorsAsList() { |
|
return Arrays.asList(getCurrentDataFlavors()); |
|
} |
|
|
|
/** |
|
* This method returns a <code>boolean</code> |
|
* indicating if the given <code>DataFlavor</code> is |
|
* supported by this <code>DropTargetContext</code>. |
|
* <P> |
|
* @param df the <code>DataFlavor</code> |
|
* <P> |
|
* @return if the <code>DataFlavor</code> specified is supported |
|
*/ |
|
|
|
protected boolean isDataFlavorSupported(DataFlavor df) { |
|
return getCurrentDataFlavorsAsList().contains(df); |
|
} |
|
|
|
/** |
|
* get the Transferable (proxy) operand of this operation |
|
* <P> |
|
* @throws InvalidDnDOperationException if a drag is not outstanding/extant |
|
* <P> |
|
* @return the <code>Transferable</code> |
|
*/ |
|
|
|
protected Transferable getTransferable() throws InvalidDnDOperationException { |
|
DropTargetContextPeer peer = getDropTargetContextPeer(); |
|
if (peer == null) { |
|
throw new InvalidDnDOperationException(); |
|
} else { |
|
if (transferable == null) { |
|
Transferable t = peer.getTransferable(); |
|
boolean isLocal = peer.isTransferableJVMLocal(); |
|
synchronized (this) { |
|
if (transferable == null) { |
|
transferable = createTransferableProxy(t, isLocal); |
|
} |
|
} |
|
} |
|
|
|
return transferable; |
|
} |
|
} |
|
|
|
/** |
|
* Get the <code>DropTargetContextPeer</code> |
|
* <P> |
|
* @return the platform peer |
|
*/ |
|
|
|
DropTargetContextPeer getDropTargetContextPeer() { |
|
return dropTargetContextPeer; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected Transferable createTransferableProxy(Transferable t, boolean local) { |
|
return new TransferableProxy(t, local); |
|
} |
|
|
|
/****************************************************************************/ |
|
|
|
|
|
/** |
|
* <code>TransferableProxy</code> is a helper inner class that implements |
|
* <code>Transferable</code> interface and serves as a proxy for another |
|
* <code>Transferable</code> object which represents data transfer for |
|
* a particular drag-n-drop operation. |
|
* <p> |
|
* The proxy forwards all requests to the encapsulated transferable |
|
* and automatically performs additional conversion on the data |
|
* returned by the encapsulated transferable in case of local transfer. |
|
*/ |
|
|
|
protected class TransferableProxy implements Transferable { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
TransferableProxy(Transferable t, boolean local) { |
|
proxy = new sun.awt.datatransfer.TransferableProxy(t, local); |
|
transferable = t; |
|
isLocal = local; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public DataFlavor[] getTransferDataFlavors() { |
|
return proxy.getTransferDataFlavors(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public boolean isDataFlavorSupported(DataFlavor flavor) { |
|
return proxy.isDataFlavorSupported(flavor); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Object getTransferData(DataFlavor df) |
|
throws UnsupportedFlavorException, IOException |
|
{ |
|
return proxy.getTransferData(df); |
|
} |
|
|
|
/* |
|
* fields |
|
*/ |
|
|
|
// We don't need to worry about client code changing the values of |
|
// these variables. Since TransferableProxy is a protected class, only |
|
// subclasses of DropTargetContext can access it. And DropTargetContext |
|
// cannot be subclassed by client code because it does not have a |
|
// public constructor. |
|
|
|
|
|
|
|
*/ |
|
protected Transferable transferable; |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected boolean isLocal; |
|
|
|
private sun.awt.datatransfer.TransferableProxy proxy; |
|
} |
|
|
|
/****************************************************************************/ |
|
|
|
/* |
|
* fields |
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private DropTarget dropTarget; |
|
|
|
private transient DropTargetContextPeer dropTargetContextPeer; |
|
|
|
private transient Transferable transferable; |
|
} |