Drag and drop (DnD) is a way to transfer data in an application.
DnD allows us to transfer data by dragging a component and dropping it onto another component.
The component dragged is called the drag source; it supplies the data to be transferred.
The component dropped is called the drop target; it is the receiver of the data.
The data transfer is accomplished using a Transferable object.
Transferable is an interface in the java.awt.datatransfer package.
The Transferable interface contains the following three methods:
To enable the dragging on the component
All text components (JFileChooser, JColorChooser, JList, JTree, and JTable) have built-in drag support for DnD.
For example, suppose we have a JTextField named nameFld and a JTextArea named descTxtArea. To start using DnD between them, we need to write the following two lines of code:
We can select text in the JTextField, drag it, and drop it onto the JTextArea. The selected text in the JTextField is transferred to the JTextArea. we can also drag text from the JTextArea to the JTextField.
Transfer Actions are represented by the constants declared in the TransferHandler class:
The following code shows how to use DnD to Transfer Data Between Swing Components
If you are writing an application you will want to support the ability to transfer information between components in your application. But you will also want your application to play well with others — this includes supporting the ability to transfer information between your application and other Java applications, and between your application and native applications. The ability to transfer data takes two forms:
- Drag and drop (DnD) support. The following diagram illustrates dragging from a JList and dropping onto a JTextField component (the arrows show the path of the data):
- Clipboard transfer through cut or copy and paste. The following diagrams show cutting (or copying) from a JList and pasting onto a JTextField component:
Drag and Drop — Behind the Scenes
Let us say there is a user named Rollo, who is running a Java application. He wants to drag some text from a list and deposit it into a text field. (Note that the process is the same when dragging from a native application to a Java application.) In a nutshell, the drag and drop process works like this:
- Rollo has selected a row of text in the source component: the list. While holding the mouse button Rollo begins to drag the text — this initiates the drag gesture.
- When the drag begins, the list packages up the data for export and declares what source actions it supports, such as COPY , MOVE , or LINK .
- As Rollo drags the data, Swing continuously calculates the location and handles the rendering.
- If Rollo simultaneously holds the Shift and/or Control key during the drag, this user action is also part of the drag gesture. Typically, an ordinary drag requests the MOVE action. Holding the Control key while dragging requests the COPY action, and holding both Shift and Control requests the LINK action.
- Once Rollo drags the text over the bounds of a text field component, the target is continually polled to see if it will accept or reject the potential drop. As he drags, the target provides feedback by showing the drop location, perhaps an insertion cursor or a highlighted selection. In this case, the text field (the current target) allows both replacement of selected text and insertion of new text.
- When Rollo releases the mouse button, the text component inspects the declared source actions and any user action and then it chooses what it wants out of the available options. In this case, the text field chooses to insert the new text at the point of the drop.
- Finally, the text field imports the data.
While this might seem like a daunting process, Swing handles most of the work for you. The framework is designed so that you plug in the details specific to your component, and the rest "just works".
More on this in the next section.
We do not recommend that you create your own drag and drop support using the AWT classes. This implementation would require significant complex support internal to each component. Prior to release 1.4 when the dnd system was reworked, developers did occasionally create their own dnd support, but it does not work with sophisticated components, like tree and table, that have subtle selection and drop issues.
In computer graphical user interfaces, drag-and-drop is the action of (or support for the action of) clicking on a virtual object and dragging it to a different location or onto another virtual object. In general, it can be used to invoke many kinds of actions, or create various types of associations between two abstract objects.
Drag and Drop
Drag and drop operation enables users to do complex things intuitively.
Usually, we can drag and drop two things: data or some graphical objects. If we drag an image from one application to another, we drag and drop binary data. If we drag a tab in Firefox and move it to another place, we drag and drop a graphical component.
Figure: Drag and drop in Swing
The component where the drag operation begins must have a DragSource object registered. A DropTarget is an object responsible for accepting drops in an drag and drop operation. A Transferable encapsulates data being transferred. The transferred data can be of various type. A DataFlavor object provides information about the data being transferred.
Several Swing components have already a built-in support for drag and drop operations. In such cases, we use a TransferHandler to manage the drag and drop functionality. In situations where there is no built-in support, the we have to create everything from scratch.
Swing text drag and drop example
We will demonstrate a simple drag and drop example. We will work with built-in drag and drop support. We utilise a TransferHandler class.
In our example we have a text field and a button. We can drag a text from the field and drop it onto the button.
The text field has a built in support for dragging. We must enable it.
The TransferHandler is a class responsible for transferring data between components. The constructor takes a property name as a parameter.
Swing icon drag & drop
Some of the Java Swing components do not have built in drag support. JLabel component is such a component. We have to code the drag functionality ourselves.
The following example shows how to drag and drop icons. In the previous example, we used a text property. This time we use an icon property.
In the code example, we have two labels and a button. Each component displays an icon. The two labels enable drag gestures, the button accepts a drop gesture.
The drag support is not enabled by default for the label. We register a custom mouse adapter for both labels.
Each of the components has a TransferHandler class for an icon property. The TransferHandler is needed for both drag sources and drag targets as well.
These code lines initiate the drag support. We get the drag source. In our case it is a label instance. We get its transfer handler object and finally initiate the drag support with the exportAsDrag() method call.
Figure: Icon drag & drop example
Swing JList drop example
Some components do not have a default drop support. One of them is JList . There is a good reason for this. We do not know if the data will be inserted into one row, or two or more rows. So we must implement manually the drop support for the list component.
The following example inserts comma or space separated text into the rows of a JList component. Otherwise, the text goes into one row.
In the example, we have a text field and a list component. The text in the text field can be dragged and dropped into the list. If the text is comma separated with a comma or a space character, the words will be split into rows. If not, the text is inserted into one row.
Here we specify a drop mode. The DropMode.INSERT specifies, that we are going to insert new items into the list component. If we chose DropMode.INSERT , we would drop new items onto the existing ones.
We set a custom transfer handler class.
We enable the drag support for the text field component.
This method tests the suitability of a drop operation. We filter out the clipboard paste operations and allow only String drop operations. If the method returns false, the drop operation is cancelled.
The importData() method transfers the data from the clipboard or from the drag and drop operation to the drop location.
The Transferable is the class, where the data is bundled.
We retrieve our data.
We get a drop location for the list. We retrieve the index, where the data will be inserted.
We split the text into parts and insert it into one or more rows.
Figure: JList drop example
The previous examples used components with built-in drag and drop support. Next we are going to create a drag and drop functionality from scratch.
Swing drag Gesture
In the following example we inspect a simple drag gesture. We work with several classes needed to create a drag gesture. A DragSource , DragGestureEvent , DragGestureListener , Transferable .
This simple example demonstrates a drag gesture. The drag gesture is created when we click on a component and move a mouse pointer while the button is pressed. The example shows how we can create a DragSource for a component.
DragGesture implements two interfaces. DragGestureListener listens for drag gestures. Transferable handles data for a transfer operation. In the example, we will not transfer any data; we only demonstrate a drag gesture. The three necessary methods of the Transferable interface are left unimplemented.
Here we create a DragSource object and register it for the panel. The DragSource is the entity responsible for the initiation of the drag and drop operation. The createDefaultDragGestureRecognizer() associates a drag source and DragGestureListener with a particular component.
The dragGestureRecognized() method responds to a drag gesture.
The startDrag() method of the DragGestureEvent finally starts the drag operation. We specify two parameters: the cursor type and the Transferable object.
The object that implements the Transferable interface must implement these three methods. There is not functionality yet.
A complex drag and drop example
In the following example, we create a complex drag and drop example. We create a drag source a drop target and a transferable object.
The code example shows a button and two panels. The button displays a colour chooser dialog and sets a colour for the first panel. The colour can be dragged into the second panel.
This example enhances the previous one. We will add a drop target and a custom transferable object.
We register a drop target listener with the right panel.
The startDrag() method has two parameters. A cursor and a Transferable object.
In the MyDropTargetListener we create a drop target object.
We get the data being transferred. In our case it is a colour object. Here we set the colour of the right panel.
If the conditions for a drag and drop operation are not fulfilled, we reject it.
In the TransferableColor , we create a new DataFlavor object.
Here we specify, what data flavors we support. In our case it is a custom defined colour flavor and a predefined DataFlavor.stringFlavor .
The getTransferData() return an object for a specific data flavour.
This part of the Java Swing tutorial was dedicated to Swing drap and drop operations.