CONTENTS | PREV | NEXT | Drag and Drop |
The Java.awt.Component class has two additional methods added to allow the (dis)association with a DropTarget. In particular:
public class java.awt.Component /* ... */ { // ... public synchronized void setDropTarget(DropTarget dt); public synchronized DropTarget getDropTarget(DropTarget df); // }
To associate a DropTarget with a Component one may invoke either; DropTarget.setCompononent() or Component.setDropTarget() methods. Thus conforming implementations of both methods are required to guard against mutual recursive invocations.To disassociate a DropTarget with a Component one may invoke either; DropTarget.setCompononent(null) or Component.setDropTarget(null) methods.
Conformant implementations of both setter methods in DropTarget and Component should be implemented in terms of each other to ensure proper maintenance of each other's state.
The setDropTarget() method throws IllegalArgumentException if the DropTarget actual parameter is not suitable for use with this class/instance of Component. It may also throw UnsupportedOperationException if, for instance, the Component does not support external setting of a DropTarget.
A caller of the setDropTarget() method requires the AWTPermission: "setDropTarget", if the caller does not have this permission then setDropTarget() will throw a SecurityException.
A DropTarget encapsulates all of the platform-specific handling of the Drag and Drop protocol with respect to the role of the recipient or destination of the operation.A single DropTarget instance may typically be associated with any arbitrary instance of java.awt.Component. Establishing such a relationship exports the associated Component's geometry to the client desktop as being receptive to Drag and Drop operations when the coordinates of the logical cursor intersects that visible geometry.
The DropTarget class is defined as follows:
public class java.awt.dnd.DropTarget implements DropTargetListener, Serializable { public DropTarget(); public DropTarget(Component c); public DropTarget(Component c, DropTargetListener dsl); public Component getComponent(); public void setComponent(Component c); public DropTargetContext getDropTargetContext(); public void addDropTargetListener(DropTargetListener dte) throws TooManyListenersException; public void removeDropTargetListener(DropTargetListener dte); public void setActive(boolean active); public boolean isActive(); public FlavorMap getFlavorMap(); protected DropTargetContext createDropTargetContext(); public void addNotify(ComponentPeer cp); public void removeNotify(ComponentPeer cp); }
The setComponent() method throws IllegalArgumentException if the Component actual parameter is not appropriate for use with this class/instance of DropTarget, and may also throw UnsupportedOperationException if the Component specified disallows the external setting of a DropTarget.For security reasons, callers of setComponent() require the AWTPermission "setDropTarget" otherwise a SecurityException shall be thrown.
The addDropTargetListener() and removeDropTargetListener() methods allow the unicast DropTargetListener to be changed.
The setActive() and isActive() methods allow the DropTarget to be made active or otherwise and for its current state to be determined.
The getFlavorMap() methods is used to obtain the FlavorMap associated with this DropTarget for the purposes of mapping any platform dependent type names to/from their corresponding platform independent DataFlavors.
The createDropTargetContext() method is typically only invoked to provide the underlying platform dependent peer with an instantiation of a new DropTargetContext as a Drag operation initially encounters the Component associated with the DropTarget. If no DropTargetContext is currently associated with a DropTarget, a permitted side-effect of an invocation of getDropTargetContext() is to instantiate a new DropTargetContext.
The addNotify() and removeNotify() methods are only called from Component to notify the DropTarget of the Component's (dis)association with its ComponentPeer.
As the logical cursor associated with an ongoing Drag and Drop operation first intersects the visible geometry of a Component with an associated DropTarget, the DropTargetContext associated with the DropTarget is the interface, through which, access to control over state of the recipient protocol is achieved from the DropTargetListener.The DropTargetContext interface is defined as follows:
public class DropTargetContext { public DropTarget getDropTarget(); public Component getComponent(); public DataFlavor[] getDataFlavors(); public void getTransferable() throws InvalidDnDOperationException; public void dropComplete(boolean success) throws InvalidDnDOperationException; protected void acceptDrop(int action); protected void rejectDrop(); public void addNotify(DropTargetContextPeer dtcp); public void removeNotify(); protected Transferable createTransferableProxy(Transferable t, boolean isLocal ); }
The getDataFlavors() method returns an array of the DataFlavors available from the DragSource.The getTransferable() method returns a Transferable (not necessarily the one the DragSource registered, it may be a proxy, and certainly shall be in the inter-JVM case) to enable data transfers to occur via its getTransferData() method. Note that it is illegal to invoke getTransferData() without first invoking an acceptDrag().
The addNotify() and removeNotify() methods are exclusively called by the underlying platform's DropTargetContextPeer in order to notify the DropTargetContext that a DnD operation is occurring/ceasing on the DropTargetContext and associated DropTarget.
The createTransferableProxy() method enables a DropTargetContext implementation to interpose a Transferable between the DropTargetListener and the Transferable provided by the caller, which is typically the underlying platform DropTargetContextPeer.
Providing the appropriate "Drag-under" feedback semantics, and processing of any subsequent Drop, is enabled through the DropTargetListener asssociated with a DropTarget.The DropTargetListener determines the appropriate "Drag-under" feedback and its response to the DragSource regarding drop eligibility by inspecting the sources suggested actions and the data types available.
A particular DropTargetListener instance may be associated with a DropTarget via addDropTargetListener() and removed via removeDropTargetListener() methods.
public interface java.awt.dnd.DropTargetListener extends java.util.EventListener { void dragEnter (DropTargetDragEvent dtde); void dragOver (DropTargetDragEvent dtde); void dragExit (DropTargetDragEvent dtde); void drop (DropTargetDropEvent dtde); }
The dragEnter() method of the DropTargetListener is invoked when the hotspot of the logical "Drag" Cursor intersects a visible portion of the DropTarget's associated Component's geometry. The DropTargetListener, upon receipt of this notification, shall interrogate the operations or actions, and the types of the data (DataFlavors) as supplied by the DragSource to determine the appropriate actions and "Drag-under" feedback to respond with invocation of either acceptDrag() or rejectDrag().The dragOver() method of the DropTargetListener is invoked while the hotspot of the logical "Drag" Cursor, in motion, continues to intersect a visible portion of the DropTarget's associated Component's geometry. The DropTargetListener, upon receipt of this notification, shall interrogate the operation "actions" and the types of the data as supplied by the DragSource to determine the appropriate "actions" and "Drag-under" feedback to respond with an invocation of either acceptDrag() or rejectDrag().
The getCursorLocation() method return the current co-ordinates, relative to the associated Component's origin, of the hotspot of the logical "Drag" cursor.
The getSourceActions() method return the current "actions", or operations (ACTION_MOVE, ACTION_COPY, or ACTION_REFERENCE) the DragSource associates with the current Drag and Drop gesture.
The dragExit() method of the DropTargetListener is invoked when the hotspot of the logical "Drag" Cursor ceases to intersect a visible portion of the DropTarget's associated Component's geometry. The DropTargetListener, upon receipt of this notification, shall undo any "Drag-under" feedback effects it has previously applied.
The drop() method of the DropTargetListener is invoked as a result of the DragSource invoking its commitDrop() method. The DropTargetListener, upon receipt of this notification, shall perform the operation specified by the return value of the getSourceActions() method on the DropTargetDropEvent object, upon the Transferable object returned from the getTransferable() method, and subsequently invoke the dropComplete() method of the associated DropTargetContext to signal the success, or otherwise, of the operation.
The DropTargetEvent and DropTargetDragEvent are defined as follows:
public abstract class java.awt.dnd.DropTargetEvent extends java.util.EventObject1 { public DropTargetContext getDropTargetContext(); }
A DropTargetEvent is passed to the DropTargetListener's dragExit() method.
public class java.awt.dnd.DropTargetDragEvent extends java.awt.dnd.DropTargetEvent { public DataFlavor[] getDataFlavors(); Point getCursorLocation(); public int getSourceActions(); public void acceptDrag(int operations); public void rejectDrag(); public boolean isTransferableLocal(); }
A DropTargetDragEvent is passed to the DropTargetListener's dragEnter() and dragOver() methods.The getCursorLocation() method return the current co-ordinates, relative to the associated Component's origin, of the hotspot of the logical "Drag" cursor.
The getSourceActions() method return the current "actions", or operations (ACTION_MOVE, ACTION_COPY, or ACTION_REFERENCE) the DragSource associates with the current Drag and Drop gesture.
The getDataFlavors() method returns the available type(s), in descending order of preference of the data that is the subject of the Drag and Drop operation.
The DropTargetDropEvent is defined as follows:
public class java.awt.dnd.DropTargetDropEvent extends java.awt.dnd.DropTargetEvent { Point getCursorLocation(); public int getSourceActions(); public void acceptDrop(int dropAction); public void rejectDrop(); public boolean isTransferableLocal(); public Transferable getTransferable(); }
A DropTargetDropEvent is passed to the DropTargetListener's drop() method, as the Drop occurs (initiated by the DragSource via an invocation of commitDrop()). The DropTargetDropEvent provides the DropTargetListener with access to the Data associated with the operation, via the Transferable returned from the getTransferable() method.The return value of the getSourceActions() method is defined to be the action(s) defined by the source at the time at which the Drop occurred.
The return value of the getCursorLocation() method is defined to be the location at which the Drop occurred.
The DropTargetListener.drop() method shall invoke acceptDrop() with the selected operation as an actual parameter, prior to any invocation of getTransferData() on the Transferable associated with the Drop.
The rejectDrop() may be called to reject the Drop operation.
Many GUI Components present a scrollable "viewport" over a (potentially) large dataset. During a Drag and Drop operation it is desirable to be able to "autoscroll" such "viewports" to allow a user to navigate over such a dataset, scrolling to locate a particular member (initially not visible through the "viewport") that they wish to drop the subject of the operation upon.Components that are scrollable provide Drag "autoscrolling" support to their DropTarget by implementing the following interface:
public interface DragAutoScrollingSupport { Insets getAutoscrollInsets(); void autoScrollContent(Point cursorLocn); }
An implementing DropTarget shall repeatedly call, at least every Toolkit.getAutoscrollRepeatDelay() milliseconds, the autoScrollContent() method of its associated Component (if present), passing the current logical cursor location in Component co-ordinates, when the following conditions are met:
- If the logical cursor's hotspot intersects with the associated Component's visible geometry and the boundary region described by the Insets returned by the getAutoscrollInsets() method.
- If the logical cursor's hotspot has not moved (subject to the next condition below) for at least Toolkit.getAutoscrollInitialDelay() millseconds
- If any cursor movement subsequent to the initial triggering occurrence continues to intersect the Rectangle returned by Toolkit.getAutoscrollCursorHysteresis().
Should any of the above conditions cease to be valid, autoscrolling shall terminate until the next triggering condition occurs.In order to support Autoscrolling the Toolkit class has been augmented as follows:
public class Toolkit { // ... public int getAutoscrollInitialDelay(); // ms public int getAutoscrollRepeatDelay(); // ms public Rectangle getAutoscrollCursorHysteresis(Point cc); // ... }
The getAutoscrollCursorHysteresis() method returns a hysteresis rectangle surrounding the point specified (current cursor location) to be used for hit testing during hysteresis detection while autoscrolling.