JFC Drag and Drop Implementation

Introduction

The JFC drag-and-drop implementation involves two distinct mechanisms.

  • The drag-and-drop mechanism
  • The data  transfer mechanism

The drag-and-drop mechanism consists of the GUI elements that make up the user interface for the drag-and-drop operation and the protocol that binds drag sources to drop targets. The java.awt.dnd package provides support for the drag and drop mechanism with classes and interfaces for drag-source and the drop-target, as well as events for transferring the dragged data and providing the user operating with visual feedback. Next, the data transfer mechanism is based on the java.awt.datatransfer package. This package includes support for clipboards, data flavors based on MIME types, and transferable data.

Implementing a Drag Source

To implement a component that is a drag source, follow the steps given below:

  • Implement a drag source listener to handle drag source events using the DragSourceListener interface.
  • Implement a drag gesture to handle drag gesture events using the DragGestureListener interface.
  • Provide an implementation for the Transferable interface to handle the data transfer operation.
  • Create a DragSource object to manage drag-drop operations.
  • Create a DragGestureRecognizer object to recognize drag gestures

The following code fragment illustrates what needs to be added to a component to make it a drag source.

class dragSource extends JLabel implements DragSourceListener, DragGestureListener, Transferable {
public dragSource(String text)
{
super(text);
DragSource ds=new DragSource.getDefaultDragSource();
DragGestureRecogniser dgr=ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, this);
}
public void dragGestureRecognized(DragGestureEvent e)
{
e.startDrag(null, this,this);
}
public Object getTransferData(DataFlavor flavor){
//return object capable of transferring data
}
public DataFlavor[] getTransferDataFlavours(){
//return data flavours supported by drag source
}
public boolean isDataFlavorSupported(DataFlavor flavor)
{
// return boolean indicating if drag source supports the specified data flavor
}
//DragSourceListener interface implements

public void dragDropEnd(DragSourceDropEvent dsde){}
public void dragEnter(DragSourceDropEvent dsde){}
public void dragExit(DragSourceDropEvent dse){}
public void dragOver(DragSourceDragEvent dsde){}
public void dragActionChanged(DragSourceDragEvent dsde){}
}
 

The above code fragment defines a dragSource component that extends JLabel by implementing the DragSourceListener, DragGestureListener, and Transferable interfaces. It also creates DragSource and DragGestureRecognizer objects in the constructor. In the above code, the dragGestureRecognized method, which is a member of the DragGestureListener interface, begins the drag operation by calling DragGetsureEvent.startDrag method.

Some of the interfaces and classes that are required for implementing the drag-and-drop operations are enumerated in the following:

The DragSourceListener Interface

The DragSourceListener interface represents a listener for drag source events. Drag sources must provide an implementation for this interface to handle drag source events.

public abstract interface DragSourceListener extends Object implements EventListener {
public abstract void dragDropEnd(DragSourceDropEvent dsde){};
public abstract void dragEnter(DragSourceDropEvent dsde){};
public abstract void dragExit(DragSourceDropEvent dse){};
public abstract void dragOver(DragSourceDragEvent dsde){};
public abstract void dropActionChanged(DragSourceDragEvent event){};
}

The DragGestureListener Interface

The DragGestureListener interface represents a listener for drag gesture events. Drag sources must provide a drag gesture listener to determine when to start a drag operation.

public abstract interface DragGestureListener extends Objects implements EventListener
{
public abstract void dragGestureRecognized(DragGestureEvent event);
}

When a drag gesture listener’s dragGestureRecognized method is called, the listener should start a drag operation by calling the DragGestureEvent.startDrag method.

The DragSource Class

The DragSource class represents a source of drag and drop operations. Each component that will be a source of drag-and-drop operations requires a drag source object to manage drag-and-drop operations.

public class DragSource extends Object
{
//refer the help for list of constructive and methods.
}

Although there is a default constructor for DragSource, the best way to get a drag source is by calling the static class method getDefaultDragSource.

The DragGestureEvent Class

The DragGestureEvent class represents a drag gesture event.

public class DragGestureEvent extends EventObject
{
// refer the help for list of constructors and methods
}

Though there is a constructor for DragGestureEvent, applications do not normally create instances for this class. Drag gesture events are sent to drag gesture listeners when the user attempts to initiate a drag operation. This class has two startDrag methods to start a drag and drop operation.

Implementing a Drop Target

The steps to be followed while implementing a component that is a drop target are given below:

  • Implement a drop target listener to handle drag-and-drop events.
  • Create a DropTarget object to manage the drag and drop operations.

When creating a DropTarget object, associate it with the component that must be a drop target and the component’s drop target listener. This can be done using one of the constructors or the instance methods after creating the object.

The amount of overhead on making a component to be a drop target is minimal. The following code fragments illustrate what needs to be added to a component in order to make it a drop target.

class dropTarget extends JPanel implements DropTargetListener
{
public dropTarget()
{
super();
//create a drop target for this component
DropTarget dt=new DragTarget(this,this);
}
//DropTargetListener interface implemention 
public void dragEnter(DropTargetDragEvent dtde){}
public void dragExit(DropTargetEvent dte){}
public void dragOver(DropTargetDragEvent dtde){}
public void drop(DropTargetDropEvent dtde){}
public void dropActionChanged(DropTargetDragEvent dtde){}
}

The above code fragment defines a dropTarget component that extends JPanel with a component that implements the DropTargetListener interface. dropTarget class also instantiates a DropTarget object in the constructor.

Some of the interfaces and classes that are used by drop targets.

The DropTargetListener Interface   

The DropTargetListener interface represents the event listener for drop target events. All drop targets must provide an implementation for DropTargetListener to handle drop target events.

public abstract interface DropTargetListener extends Object implements EventListener
{
//Abstract public interface methods.
public abstract void dragEnter(DropTargetDragEvent dtde){}
public abstract void dragExit(DropTargetEvent dte){}
public abstract void dragOver(DropTargetDragEvent dtde){}
public abstract drop(DropTargetDropEvent dtde){}
public abstract void dropActionChanged(DropTargetDragEvent dtde){}
}

The dragEnter and dragExit methods notify a target when a drag operation enters and exits the area occupied by their associated components. The dragOver method is generated continuously as the cursor is moved over the target.

The DropTarget Class

The DropTarget class represents a drop target. We have to instantiate an object of this class for each component to make it a drop target.

public class DropTarget extends Object implements DropTargetListener, Serializable
{
//see the help for list of constructors and methods
}

Apart from the default constructor. DropTarget has several constructors that allow us to associate the target with a component and a drop target event listener. One can also specify the default drop actions and the data flavors the target supports, irrespective of whether the target is active or not. When a default constructor of DropTarget is instantiated, we must set the setComponent and addDropTargetListener methods to associate a component and drop target event listener with the drop target.

The DropTargetEvent class

The  DropTargetEvent class is the base class for the drop-target event classes.

DropTargetDragEvent and DropTargetDropEvent.

public class DropTargetEvent extends EventObject
{
//public constructor
public DropTargetEvent(DropTargetContent dtc){};
//public instance methods
public DropTargetContext getDropTargetContext();
}

The only method in the DropTargetEvent class is getDropTargetContext, which retrieves the context for the drop target associated with the event.

Summary 

Drag and Drop is a user interface gesture that allows users to request a data transfer between a source and a target. JFC provides a framework to support drag-and-drop gestures and to facilitate data transfer within an application as well as between applications.