package dtd;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceContext;
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;
import java.io.IOException;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
/**
* 这个监听器会发送一个startDrag()的信息给拖拽对象
*/
class MDragGestureListener implements DragGestureListener {
public void dragGestureRecognized(DragGestureEvent dge) {
Component comp = dge.getComponent();
TreePath tp = ((JTree) comp).getSelectionPath();
System.out.println(tp.toString());
if (tp != null) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tp
.getLastPathComponent();
MTransferable mt = new MTransferable(node);
dge.startDrag(DragSource.DefaultMoveDrop, mt,
new MDragSourceListener());
}
}
}
/**
* 接口负责当鼠标拖拽对象经过组件时的可视化处理
*/
class MDragSourceListener implements DragSourceListener {
public void dragDropEnd(DragSourceDropEvent dsde) {
System.out.println("MDragSourceListener : dragDropEnd");
}
public void dragEnter(DragSourceDragEvent e) {
DragSourceContext context = e.getDragSourceContext();
int dropAction = e.getDropAction();
if ((dropAction & DnDConstants.ACTION_COPY) != 0) {
context.setCursor(DragSource.DefaultCopyDrop);
} else if ((dropAction & DnDConstants.ACTION_MOVE) != 0) {
context.setCursor(DragSource.DefaultCopyDrop);
} else {
context.setCursor(DragSource.DefaultCopyNoDrop);
}
System.out.println("MDragSourceListener : dragEnter");
}
public void dragExit(DragSourceEvent dse) {
System.out.println("MDragSourceListener : dragExit");
}
public void dragOver(DragSourceDragEvent dsde) {
// System.out.println("MDragSourceListener : dragOver");
}
public void dropActionChanged(DragSourceDragEvent dsde) {
System.out.println("MDragSourceListener : dropActionChanged");
}
}
/**
* 当 drag 进入、移上或退出该 DropTarget 的 drop 位置的可操作部分时, 当 drop 操作改变时,以及当 drop 操作发生时,调用
* listener 对象的相关方法, 并将 DropTargetEvent 传递到该方法
*/
class MDropTargetListener implements DropTargetListener {
public void dragEnter(DropTargetDragEvent dtde) {
System.out.println("MDropTargetListener : dragEnter");
}
public void dragExit(DropTargetEvent dte) {
System.out.println("MDropTargetListener : dragExit");
}
public void dragOver(DropTargetDragEvent dtde) {
// System.out.println("MDropTargetListener : dragOver");
}
public void drop(DropTargetDropEvent dtde) {
Transferable transfer = dtde.getTransferable();
String s = "";
try {
if (transfer.isDataFlavorSupported(DataFlavor.stringFlavor)) {
s = transfer.getTransferData(DataFlavor.stringFlavor)
.toString();
}
} catch (Exception e) {
e.printStackTrace();
}
DropTarget dt = (DropTarget) dtde.getSource();
JTextArea d = (JTextArea) dt.getComponent();
if (s != null) {
d.append(s);
}
}
public void dropActionChanged(DropTargetDragEvent dtde) {
System.out.println("MDropTargetListener : dropActionChanged");
}
}
/**
* 定义为传输操作提供数据所使用的类的接口。
*/
class MTransferable implements Transferable {
private DataFlavor[] flavors = { DataFlavor.stringFlavor };
private Object obj;
public MTransferable(Object obj) {
this.obj = obj;
}
public Object getTransferData(DataFlavor df)
throws UnsupportedFlavorException, IOException {
return obj;
}
public DataFlavor[] getTransferDataFlavors() {
return flavors;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
for (DataFlavor df : flavors) {
if (df.equals(flavor)) {
return true;
}
}
return false;
}
}
class DndTest extends JFrame {
private static final long serialVersionUID = -7663935372828949366L;
private JScrollPane pane = new JScrollPane();
private JTextArea text = new JTextArea();
public DndTest() {
this.getContentPane().setLayout(new BorderLayout());
pane.getViewport().setBackground(Color.ORANGE);
pane.setBounds(0, 0, 300, 300);
pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
text.setBackground(Color.WHITE);
JTree tree = new JTree();
tree.setBackground(Color.ORANGE);
pane.getViewport().add(tree);
this.getContentPane().add(text, BorderLayout.SOUTH);
this.getContentPane().add(pane, BorderLayout.CENTER);
// 设置边框
text.setBorder(BorderFactory.createEtchedBorder());
DragSource ds = DragSource.getDefaultDragSource();
ds.createDefaultDragGestureRecognizer(tree,
DnDConstants.ACTION_COPY_OR_MOVE, new MDragGestureListener());
DropTarget ts = new DropTarget(text, new MDropTargetListener());
}
public static void main(String args[]) {
DndTest dt = new DndTest();
dt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
dt.setIconImage(dt.getToolkit().getImage("c:/icon/myeclipse.GIF"));
dt.setSize(400, 300);
dt.setVisible(true);
}
}
参考 http://blog.csdn.net/xumingming64398966/archive/2007/01/24/1492409.aspx
Drag Target 一个对象那个如果想作为拖拽源的话,必须和五个对象建立联系,这五个对象分别是: * java.awt.dnd.DragSource 获取DragSource的方法很简单,直接调用DragSource.getDefaultDragSource();就可以得到DragSource对象 * java.awt.dnd.DragGestureRecognizer DragGestureRecognizer类中实现了一些与平台无关的方法,我们如果想在自己的组件上实现拖拽的话只要调用createDefaultDragGestureRecognizer()方法就可以了 该方法接收三个参数,建立组件和拖拽动作之间的关系 * java.awt.dnd.DragGestureListener 当建立了组件和拖拽动作之间的联系后,如果用户执行了拖拽操作,组件将发送一个消息给DragGestureListener监听器 DragGestureListener监听器接下来会发送一个startDrag()消息给拖拽源对象,告诉组件应该执行拖拽的初始化操作了 拖拽源会产生一个DragSourceContext对象来监听动作的状态,这个监听过程是通过监听本地方法DragSourceContextPeer来实现的 * java.awt.datatransfer.Transferable * java.awt.dnd.DragSourceListener DragSourceListener接口负责当鼠标拖拽对象经过组件时的可视化处理, DragSourceListener接口的显示结果只是暂时改变组件的外观 同时他提供一个feedback,当用户的拖拽操作完成之后会收到一个dragDropEnd的消息,我们可以在这个函数中执行相应的操作 再来回顾一下拖拽源的建立过程 1.DragGestureRecognizer 确认一个拖拽操作,同时告知 DragGestureListener. 2.假如actions and/or flavors are OK, DragGestureListener 让 DragSource 调用 startDrag(). 3.DragSource建立一个 DragSourceContext和一个DragSourceContextPeer. 4.DragSourceContext 把它自己作为一个DragSourceListener,侦听DragSourceContextPeer.DragSourceContextPeer会从本地系统得到Coponent的状态改变的通知(component entered/exited/is over), 并把他们代理给DragSourceContext.5.DragSourceContext通知 DragSourceListener,而DragSourceListener提供 drag over 的反馈(如果DropTargetListener接受这个动作). 典型的反馈包括让DrogSourceContext改变鼠标.
6.一旦drop完毕, DragSourceListener就得到一个dragDropEnd的通知消息.
Drop Source 创建一个 droppable Component必须和下面两个对象发生关联 * java.awt.dnd.DropTarget DropTarget构造函数使DropTarget 和 DropTargetListener objects发生关联 Droptarget对象提供 setComponent 和addDropTargetListener 两个方法 * java.awt.dnd.DropTargetListener
DropTargetListener需要与一个Component联系, 以让DropTargetListener在Component操作的时候能够显示”drag under”效果.
</script>