11.10.2 拖放源

11.10.2 拖放源

前面程序使用DropTarget创建了一个拖放目标,直接使用系统资源管理器作为拖放源。下面介绍如何在Java程序中创建拖放源,创建拖放源比创建拖放目标要复杂一些,因为程序需要把被拖放内容封装成Transferable对象。

创建拖放源的步骤如下。

1、调用DragSource的getDefaultDragSourceO方法获得与平台关联的DragSource对象。
2、调用DragSource对象的createDefaultDragGestureRecognizer(Component c,int actions.DragGestureListener dgl)方法将指定组件转换成拖放源。其中actions用于指定该拖放源可接受哪些拖放操作,而dgl是一个拖放监听器,该监听器里只有一个方法:dragGestureRecognized(),当系统检测到用户开始拖放时将会触发该方法。

如下代码将会把一个JLabel对象转换为拖放源。

1
2
// 将srcLabel组件转换为拖放源
dragSource.createDefaultDragGestureRecognizer(srcLabel,DnDConstants.ACTION_COPY_OR_MOVE,new MyDragGestureListener())

3、 为第2步中的DragGestureListener监听器提供实现类,该实现类需要重写该接口里包含的dragGestureRecognized()方法,该方法负责把拖放内容封装成Transferable对象。

下面程序示范了如何把一个JLabel转换成拖放源。

import java.awt.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;

import javax.swing.*;

public class DragSourceTest
{
    JFrame jf = new JFrame("Swing的拖放支持");
    JLabel srcLabel = new JLabel("Swing的拖放支持.\n"
        +"将该文本域的内容拖入其他程序.\n");
    public void init()
    {
        DragSource dragSource = DragSource.getDefaultDragSource();
        // 将srcLabel转换成拖放源,它能接受复制、移动两种操作
        dragSource.createDefaultDragGestureRecognizer(srcLabel
            , DnDConstants.ACTION_COPY_OR_MOVE
            , event -> {
            // 将JLabel里的文本信息包装成Transferable对象
            String txt = srcLabel.getText();
            Transferable transferable = new StringSelection(txt);
            // 继续拖放操作,拖放过程中使用手状光标
            event.startDrag(Cursor.getPredefinedCursor(Cursor
                .HAND_CURSOR), transferable);
        });
        jf.add(new JScrollPane(srcLabel));
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);
    }
    public static void main(String[] args)
    {
        new DragSourceTest().init();
    }
}

上面程序中粗体字代码负责把一个JLabel组件创建成拖放源,创建拖放源时指定了一个DragGestureListener对象,该对象的dragGestureRecognized)方法负责将JLabel上的文本转换成Transferable对象后继续拖放。

运行上面程序后,可以把程序窗口中JLabel标签的内容直接拖到Eclipse编辑窗口中,或者直接拖到EditPlus编辑窗口中。

除此之外,如果程序希望能精确监听光标在拖放源上的每个细节,则可以调用DragGestureEvent对象的startDrag(Cursor dragCursor,Transferable transferable,DragSourceListener dsl)方法来继续拖放操作。该方法需要一个DragSourceListener监听器对象,该监听器对象里提供了如下几个方法。

  • dragDropEnd(DragSourceDropEvent dsde):当拖放操作已经完成时将会触发该方法。
  • dragEnter(DragSourceDragEvent dsde):当光标进入拖放源组件时将会触发该方法。
  • dragExit(DragSourceEvent dse):当光标离开拖放源组件时将会触发该方法。
  • dragOver(DragSourceDragEvent dsde):当光标在拖放源组件上移动时将会触发该方法。
  • dropActionChanged(DragSourceDragEvent dsde):当用户在拖放源组件上改变了拖放操作,例如按下或松开Ctrl等辅助键时将会触发该方法。

掌握了开发拖放源、拖放目标的方法之后,如果接下来在同一个应用程序中既包括拖放源,也包括拖放目标,这样即可在同一个Java程序的不同组件之间相互拖动内容。