Home >> Java
Drag and Drop (DnD) using Java Technology. A simple to understand article to the
best of my understanding about Java Technology Drag and Drop.
While creating Drag and Drop functionality using Java API, there are some of the basic
points, as follows:
1. At least one DragSource, instantiated/associated with the component that is to be
drag and drop.
2. At least one DropTarget that is to be instantiated
or associated with component that is used as the container
for the dropped component to reside.
3. Three main type of listeners, those will be notified as
and when particular event triggers while doing drag and drop
operation.
These are:
3.1. DragSourceListener, notifies when DragSourceEvent,
DragSourceDragEvent and DragSourceDropEvent trigger.
3.2. DragGestureListener, gets notification if
DragGestureEvent id triggered.
3.3. DropTargetListener, gets notification of DropTargetEvent,
DropTargetDragEvent, DropTargetDropEvent triggers.
|
|  |
|
4. The component that is to be dragged should create a
DragGestureRecognizer, simple way is to create a default
DragGestureRecognizer, by calling a method
DragSource.createDragGestureRecognizer method.
So we have three different areas to this explanation.
One -> The main frame on which both components, drag and drop
components.
Two -> The component to be dragged, for my example, I choose
java.awt.Button.
For this sample, I defined a customized, button that extends
java.awt.Button and implements two event listeners such as
DragSourceListener, DragGestureListener.
Three -> The component on top of it we are going to
drag this customized button, is a customized Panel.
This Panel extends java.awt.Panel and implements event
listener specific to DnD operation is DropTargetListener.
Now listeners are in place, and DragGesture recognizer ready
to recognizer and DragSource and DropTarget are ready to be
notified, but actual drag operation has to be started by
DragGestureRecognizer, in this case it is our customized
Button.
But one interesting point I found/observed that actually Button
is not moving even after startDrag operation is invoked.
I had to write a specific way to check for the x,y points
of mouse pointer/cursor during drag operation, extract dragSource
component and move it to the new location and place it on the
drop location.
This is one doubt I have, when I have to manually move drag
component, then I can actually do this by using mouse motion
and mouse listener,
Why I have to use Drag and Drop classes? You can reply your answers
here.
-----------------------------------------------------------------------
/**
* This code is a sample code
* provided "AS IS" without any warranty.
* Date: 20-October-2007
* E-mail: usingframeworks@gmail.com
*/
import java.awt.Button;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
public class TestDragDrop extends Frame {
TestPanel testPanel = null;
TestButton testButton = null;
public TestDragDrop() {
setSize(300,300);
testPanel = new TestPanel();
testPanel.setSize(300,300);
testPanel.setBackground(Color.LIGHT_GRAY);
testButton = new TestButton("Test");
testPanel.add(testButton);
add(testPanel);
show();
}
public static void main(String args[]) {
new TestDragDrop();
}
}
class TestPanel extends Panel implements DropTargetListener {
DropTarget dt;
public TestPanel() {
dt = new DropTarget(this, DnDConstants
.ACTION_COPY_OR_MOVE, this);
}
public void dragEnter(DropTargetDragEvent arg0) {
}
public void dragExit(DropTargetEvent arg0) {
}
public void dragOver(DropTargetDragEvent arg0) {
Constant.x = arg0.getLocation().x;
Constant.y = arg0.getLocation().y;
}
public void drop(DropTargetDropEvent arg0) {
}
public void dropActionChanged(DropTargetDragEvent arg0) {
}
}
class TestButton extends Button implements DragSourceListener,
DragGestureListener {
DragSource ds = DragSource.getDefaultDragSource();
public TestButton(String label) {
super(label);
ds.createDefaultDragGestureRecognizer(this,
DnDConstants.ACTION_COPY_OR_MOVE, this);
}
public void dragGestureRecognized(DragGestureEvent arg0) {
Transferable t = new StringSelection(getLabel());
arg0.startDrag(DragSource.DefaultMoveDrop, t, this);
}
public void dragDropEnd(DragSourceDropEvent arg0) {
}
public void dragEnter(DragSourceDragEvent arg0) {
}
public void dragExit(DragSourceEvent arg0) {
}
public void dragOver(DragSourceDragEvent arg0) {
arg0.getDragSourceContext().getComponent()
.setLocation(Constant.x, Constant.y);
}
public void dropActionChanged(DragSourceDragEvent arg0) {
}
}
class Constant {
public static int x;
public static int y;
}
-----------------------------------------------------------------------
If interested in writing about this article, please do so
by sending an email to me. My email id is
"usingframeworks at gmail . com".
We could do the same thing like this for example
Add a frame (MainFrame)
Add a panel(MainPanel) on the frame
Add a button (MoveButton) on the panel
Add a MouseDragged event for the button and in the event
write the code as follows
MoveButton.setLocation( MainPanel.getMousePosition().x ,
MainPanel.getMousePosition().y );
Thats it that will allow you to drag and drop the button .
Now my question is when you try to drag the button the mouse
pointer goes to the (0,0) co-ordinate location of the button.
I want the mouse pointer to stay where i begin to drag .
The same is happening with your code as well . How could we
solve this .
I think it can be solved by adjusting actual mouse click X and Y
points with the position of the upper left corner of this component.
I shall work on this and shall come up with a sample code and
provide it here.
In the mean time if you have any other way of doing it, please
let us know.
This is the solution I was trying to mention in my earlier
proposed solution:
In TestDragDrop constructor, put this code for getting mouse
clicked position:
testButton.addMouseListener(new java.awt.event.MouseAdapter(){
public void mousePressed(java.awt.event.MouseEvent me) {
Constant.xx = me.getX();
Constant.yy = me.getY();
}
public void mouseReleased(java.awt.event.MouseEvent me) {
Constant.xx = 0;
Constant.yy = 0;
}
});
Define two more constants in Constant class file as follows:
public static int xx;
public static int yy;
By changing setLocation method arguments (from dragOver method)
from setLocation(Constant.x, Constant.y);
to setLocation(Constant.x-xx;Constant.y-Constant.yy);
Idea here is to capture location of the mouse pressed event
to know exactly where the mouse pointer was present at the
time of mouse button is pressed.
Once the mouse pointer position/location is found, then it cane
be put in constant as xx and yy variables.
By subtracting this value from the dynamic value of x and y,
mouse pointer is shown at the desired location while dragging.
Please let me know if you have anything other solution and want
it to be discussed.
Thanks.
If anything missed out , please let me know at
techienjoy at yahoo . com