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>