首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 拖放功能實現:DragSource、DropTarget、Transferable 完整指南

     編輯:Java 程式設計入門

核心架構

Java DnD (Drag and Drop) 基於 java.awt.dnd 與 java.awt.datatransfer 兩大包。核心概念:

  • DragSource:拖曳源,發起拖曳、提供資料 (Transferable)。
  • DropTarget:放置目標,接收資料。
  • Transferable:資料載體,支援多種 DataFlavor (MIME 類型)。
  • DragGestureListener:識別拖曳手勢 (按下+移動)。
  • DragSourceListener / DropTargetListener:拖曳過程/放置事件回呼。

完整範例:標籤拖曳文字到文字框

public class DnDDemo extends JFrame
        implements DragGestureListener, DragSourceListener, DropTargetListener {

    private final DragSource dragSource = DragSource.getDefaultDragSource();
    private final JLabel lblSource = new JLabel("Hello World!", SwingConstants.CENTER);
    private final JTextField txtTarget = new JTextField();
    private final DropTarget dropTarget;

    public DnDDemo() {
        setLayout(new BorderLayout());
        add(lblSource, BorderLayout.NORTH);
        add(txtTarget, BorderLayout.SOUTH);
        setSize(400, 150);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        // 1. 註冊拖曳源
        dragSource.createDefaultDragGestureRecognizer(lblSource,
                DnDConstants.ACTION_COPY_OR_MOVE, this);

        // 2. 註冊放置目標
        dropTarget = new DropTarget(txtTarget, DnDConstants.ACTION_COPY_OR_MOVE, this);
    }

    // === DragGestureListener ===
    public void dragGestureRecognized(DragGestureEvent dge) {
        Transferable t = new StringSelection(lblSource.getText());
        dge.startDrag(DragSource.DefaultCopyDrop, t, this);
    }

    // === DragSourceListener (視覺回饋) ===
    public void dragEnter(DragSourceDragEvent dsde) {
        dsde.getDragSourceContext().setCursor(
                (dsde.getDropAction() & DnDConstants.ACTION_COPY) != 0
                        ? DragSource.DefaultCopyDrop : DragSource.DefaultCopyNoDrop);
    }
    public void dragOver(DragSourceDragEvent dsde) {}
    public void dropActionChanged(DragSourceDragEvent dsde) {}
    public void dragExit(DragSourceEvent dse) {}
    public void dragDropEnd(DragSourceDropEvent dsde) {}

    // === DropTargetListener ===
    public void drop(DropTargetDropEvent dtde) {
        try {
            Transferable t = dtde.getTransferable();
            if (dtde.isDataFlavorSupported(DataFlavor.stringFlavor)) {
                dtde.acceptDrop(dtde.getDropAction());
                String s = (String) t.getTransferData(DataFlavor.stringFlavor);
                txtTarget.setText(txtTarget.getText() + s);
                dtde.dropComplete(true);
            } else {
                dtde.rejectDrop();
            }
        } catch (Exception ex) { ex.printStackTrace(); dtde.rejectDrop(); }
    }
    public void dragEnter(DropTargetDragEvent dtde) {}
    public void dragOver(DropTargetDragEvent dtde) {}
    public void dropActionChanged(DropTargetDragEvent dtde) {}
    public void dragExit(DropTargetEvent dte) {}

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new DnDDemo().setVisible(true));
    }
}

關鍵點詳解

介面/類核心方法說明
DragSourcecreateDefaultDragGestureRecognizer綁定元件、動作類型、手勢監聽器
DragGestureListenerdragGestureRecognized建立 Transferable、呼叫 startDrag
TransferablegetTransferDataFlavors, isDataFlavorSupported, getTransferData資料封裝,支援多種 MIME 類型
DropTarget建構子綁定元件、動作、監聽器自動處理原生 DnD 協議
DropTargetListener.dropacceptDrop, getTransferData, dropComplete接收資料、寫入目標元件、通知完成

進階主題

  • 自定義 DataFlavor:實現 Transferable 支援自定義物件序列化 (如 application/x-java-serialized-object)。
  • 拖曳圖片/檔案:DataFlavor.imageFlavor、DataFlavor.javaFileListFlavor (返回 List)。
  • Swing 元件內建支援:JTable、JList、JTree 設定 setDragEnabled(true)、setDropMode(DropMode.INSERT) 即可獲得基本 DnD,無需手寫監聽器。
  • 跨 JVM/進程拖曳:需資料實現 Serializable 並使用 java.io.serialization Flavor。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved