|
|
The program behind the application shown in Figure 16.1 follows. Be sure to try pasting from external applications, not just from what was copied with the program.
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.*;
import java.awt.datatransfer.*;
import java.io.IOException;
public class ClipIt {
public static void main (String args[]) {
final Clipboard clipboard =
Toolkit.getDefaultToolkit().getSystemClipboard();
JFrame f = new JFrame ("Clip It");
f.addWindowListener (new WindowAdapter() {
public void windowClosing (WindowEvent e) {
System.exit (0);
}
});
Container c = f.getContentPane();
final JTextArea jt = new JTextArea();
JScrollPane pane = new JScrollPane (jt);
c.add (pane, BorderLayout.CENTER);
JButton copy = new JButton ("Copy");
copy.addActionListener (new ActionListener() {
public void actionPerformed (ActionEvent e) {
String selection = jt.getSelectedText();
StringSelection data = new StringSelection(
selection);
clipboard.setContents (data, data);
}
});
JButton paste = new JButton ("Paste");
paste.addActionListener (new ActionListener() {
public void actionPerformed (ActionEvent e) {
Transferable clipData = clipboard.getContents
(clipboard);
if (clipData != null) {
try {
String s = (String)(clipData.getTransferData
(
DataFlavor.stringFlavor));
jt.replaceSelection (s);
} catch (UnsupportedFlavorException ee) {
System.err.println ("Unsupported flavor:
" + ee);
} catch (IOException ee) {
System.err.println ("Unable to get data:
" + ee);
}
}
}
});
JPanel p = new JPanel();
p.add (copy);
p.add (paste);
c.add (p, BorderLayout.SOUTH);
f.setSize (300, 300);
f.setVisible (true);
}
}
Drag and DropDrag and drop within Java is similar to accessing the clipboard, except the process of moving the data is a little more complicated. The data that you wish to transfer still needs to implement theTransferable
interface. Besides the data to transfer, there is a source and a destination.
The source of the dragging implements the DragSourceListener
interface:
public interface DragSourceListener
extends EventListener{
public abstract void dragDropEnd(
DragSourceDropEvent e);
public abstract void dragEnter(
DragSourceDragEvent e);
public abstract void dragExit(
DragSourceEvent e);
public abstract void dragOver(
DragSourceDragEvent e);
public abstract void dropActionChanged(
DragSourceDragEvent e);
}
While the target implements
public interface DropTargetListener
extends EventListener{
public abstract void
dragEnter(DropTargetDragEvent e);
public abstract void
dragExit(DropTargetEvent e);
public abstract void
dragOver(DropTargetDragEvent e);
public abstract void
drop(DropTargetDropEvent e);
public abstract void
dropActionChanged(DropTargetDragEvent e);
}
One thing should be pointed out. There are three different event types for
each set of five methods:
The source of a dragging is a
public class DragSource extends Object{
public static final Cursor DefaultCopyDrop;
public static final Cursor DefaultCopyNoDrop;
public static final Cursor DefaultLinkDrop;
public static final Cursor DefaultLinkNoDrop;
public static final Cursor DefaultMoveDrop;
public static final Cursor DefaultMoveNoDrop;
public DragSource();
public static DragSource getDefaultDragSource();
public static boolean isDragImageSupported();
public DragGestureRecognizer
createDefaultDragGestureRecognizer(
Component target,
int actions,
DragGestureListener l);
public DragGestureRecognizer
createDragGestureRecognizer(
Class recognizerAbstractClass,
Component target,
int actions,
DragGestureListener l);
protected DragSourceContext createDragSourceContext(
DragSourceContextPeerdscp,
DragGestureEvent dgl,
Cursor dragCursor,
Image dragImage,
Point imageOffset,
Transferable t,
DragSourceListener l);
public FlavorMap getFlavorMap();
public void startDrag(
DragGestureEvent trigger,
Cursor dragCursor,
Image
dragImage,
Point dragOffset,
Transferable t,
DragSourceListener l)
throws InvalidDnDOperationException
public void startDrag(
DragGestureEvent trigger,
Cursor dragCursor,
Image
dragImage,
Point imageOffset,
Transferable t,
DragSourceListener l,
FlavorMap map)
throws
InvalidDnDOperationException;
public void startDrag(
DragGestureEvent trigger,
Cursor dragCursor,
Transferable t,
DragSourceListener l)
throws InvalidDnDOperationException;
public void startDrag(
DragGestureEvent trigger,
Cursor dragCursor,
Transferable t,
DragSourceListener l,
FlavorMap map)
throws InvalidDnDOperationException;
The other thing you must do in the constructor is create a
public interface DragGestureListener
extends EventListener {
public abstract void dragGestureRecognized(
DragGestureEvent e);
}
It is within this
To put all this together, create a draggable
import java.awt.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import com.sun.java.swing.*;
import com.sun.java.swing.event.*;
public class DraggableLabel extends JLabel implements
DragSourceListener,
DragGestureListener {
DragSource dragSource;
public DraggableLabel(String s) {
super (s);
dragSource = new DragSource();
dragSource.createDefaultDragGestureRecognizer(
this, DnDConstants.ACTION_COPY, this);
}
public void dragGestureRecognized(
DragGestureEvent e) {
StringSelection text =
new StringSelection(getText());
dragSource.startDrag(
e,
DragSource.DefaultCopyDrop,
text,
this);
}
public void dragDropEnd (DragSourceDropEvent e){}
public void dragEnter (DragSourceDragEvent e){}
public void dragExit (DragSourceEvent e){}
public void dragOver (DragSourceDragEvent e){}
public void dropActionChanged
(DragSourceDragEvent e){}
}
The only part not explained yet is the
public final class DnDConstants {
public static final int ACTION_COPY;
public static final int ACTION_COPY_OR_MOVE;
public static final int ACTION_LINK;
public static final int ACTION_MOVE;
public static final int ACTION_NONE;
public static final int ACTION_REFERENCE;
public DnDConstants();
}
The component you'll drop the draggable label into is a
import java.awt.*;
import java.awt.dnd.*;
import com.sun.java.swing.*;
import java.awt.datatransfer.*;
import java.io.IOException;
import java.util.Vector;
public class DroppableList extends JList
implements DropTargetListener {
DropTarget dropTarget;
Vector v = new Vector();
public DroppableList() {
dropTarget = new DropTarget (this, this);
}
public void dragEnter (DropTargetDragEvent e){
e.acceptDrag (DnDConstants.ACTION_COPY);
}
public void dragExit (DropTargetEvent e){
}
public void dragOver (DropTargetDragEvent e){
}
public void drop (DropTargetDropEvent e){
try {
Transferable tr = e.getTransferable();
if (tr.isDataFlavorSupported (
DataFlavor.stringFlavor)) {
e.acceptDrop
(DnDConstants.ACTION_COPY_OR_MOVE);
String s = (String)tr.getTransferData (
DataFlavor.stringFlavor);
v.add (s);
setListData (v);
paintImmediately(getVisibleRect());
e.getDropTargetContext().dropComplete(true);
} else {
System.err.println ("Rejected");
e.rejectDrop();
}
} catch (IOException io) {
io.printStackTrace();
e.rejectDrop();
} catch (UnsupportedFlavorException ufe){
ufe.printStackTrace();
e.rejectDrop();
}
}
public void dropActionChanged
(DropTargetDragEvent e){
}
}
To demonstrate the droppable list and draggable label, Figure 16.2 shows a program with four labels around the list after several drag operations.
The test program behind Figure 16.2 is below:
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.*;
import com.sun.java.swing.event.*;
public class Tester {
public static void main (String args[]) {
Frame f = new Frame("Tester");
DraggableLabel north = new DraggableLabel(
"One");
DraggableLabel south = new DraggableLabel(
"Two");
DraggableLabel east = new DraggableLabel(
"Three");
DraggableLabel west = new DraggableLabel(
"Four");
DroppableList list = new DroppableList();
JScrollPane pane = new JScrollPane (list);
f.add (north, BorderLayout.NORTH);
f.add (south, BorderLayout.SOUTH);
f.add (east, BorderLayout.EAST);
f.add (west, BorderLayout.WEST);
f.add (pane, BorderLayout.CENTER);
f.setSize (300, 300);
f.addWindowListener (new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.setVisible (true);
}
}
SummaryThis chapter described how you deal with transferring data, both with clipboards and with drag and drop operations. While the tasks are definitely different, they share several common characteristics. By understanding theTransferable interface, as well as the DataFlavor
way of dealing with the data, you should have no problem with either operation.
About the AuthorJohn Zukowski is a Software Mage with MageLang Institute. In addition to being the author of Mastering Java 2, Java AWT Reference, and Borland JBuilder: No Experience Required. John also serves as the Focus on Java Guide at The Mining Co.
Reader FeedbackTell us what you think of this book excerpt.
|