对SWT控件的拖放深入了解(二)

DropTarget

通过创建一个DropTarget来注册一个控件使其具有接收拖放的能力,例如:

DropTarget target = new DropTarget(table, DND.DROP_COPY | DND.DROP_DEFAULT);

其中第二个参数定义释放目标允许的操作。在鼠标拖动的过程中,我们可以通过鼠标图形的变化来得知当前经过的是否是一个有效的DropTarget,这个过程叫做“drag over effect”。鼠标图形同时也可以告诉我们在数据被Drop之后,什么样的操作会被执行,是拷贝还是移动还是别的什么。之后需要通过setTransfer方法设定允许接收的数据类型。一个示例:

int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK;

Transfer[] types = new Transfer[] {TextTransfer.getInstance()};//和源一样可定义多种Tranfer

DropTarget target = new DropTarget(label, operations);

target.setTransfer(types);

最后需要为Target添加监听器:addDropListener(new DorpTargetListener()); 监听器的所有方法的参数都是DropTargtEvent,它有几个重要的属性:

a)       currentDataType:将要释放的数据的类型。它是一个TransferData类的实例,我们无需知道其具体值,因为这种类是给Transfer判断是非支持用的:Transfer.isSupportedType(transferData).

b)       dataTypes: DragSource可提供的数据类型的集合(TransferData类的集合)

c)       operations:可提供的操作的集合,是源和目标允许操作的交集;

d)       detail:拖放完成时将被执行的操作

e)       data:存放拖放的数据

监听器包含的方法有:

l        dragEnter(DropTargtEvent event): 光标进入目标对象区域时触发. 此方法一般用来定义拖放的操作类型,即给event.detail赋值; event.detail的值确定了最终拖放到底执行什么操作。
event.detail的值只能是event.operations中的某一个, 或者是DND.DROP_NONE(也就是不产生任何操作)。而event.operations则是拖放源DragSource支持的所有操作(创建时输入的第二个参数)与目的DropTarget支持的所有操作的交集。(这部分是所有教材都未提到的,包括一些国外教材如《SWT/JFace in Action》也没说清楚)它本身是一个整数,通过观察其二进制数的各位是否为1可知道包含了哪些操作(可通过按位与运算获知)。
DropTarget在创建时可增加DND.DROP_DEFAULT参数,表示允许定义默认操作,但它具体指哪个操作需要在本方法中定义,也就是给DND.DROP_DEFAULT指定一个具体的操作。如果在本方法中和在dragOperationChanged()中都没给它定义,则它会被系统定义为DND.DROP_MOVE。DND.DROP_DEFAULT的目的就是为了判断拖动的过程中如果有没有辅助按键被按下,没有的话event.detail就等于DND.DROP_DEFAULT,这时就可指定event.detail来实现默认操作。例如:

if(event.detail==DND.DROP_DEFAULT){

          //给event.detail赋的值必须是event.operations中的一个,event.operations中的操作都是DragSource所支持的.

          if((event.operations&DND.DROP_COPY)!=0){

            event.detail=DND.DROP_COPY;

          }else{

            event.detail=DND.DROP_NONE;

          }

        }

拖放中如果按了辅助键,自然就不再是默认操作了,辅助键产生的影响在方法dragOperationChanged()中定义。

l        dragOver(DropTargtEvent event): 光标进入目标对象区域中的事件,只要光标在区域中,该事件会不停触发,即使光标不动。通常在对表格或树拖动时要用到这个方法,和event.feedback属性

l        dragOperationChanged(DropTargtEvent event):用户按下或放开辅助键时触发的事件,辅助键的定义根据本地系统而定;但辅助键定义的事件必须是包含在event.operations中的,否则无效(event.detail变成DND.DROP_NONE)。在operations允许的前提下:

n        拖放时按住Ctrl,event.detail变成DND.DROP_COPY;

n        按住Shift,event.detail变成DND.DROP_MOVE;

n        同时按住CTRL+SHIFT,event.detail变成DND.DROP_LINK;

n        放开辅助键则event.detail变成DND.DROP_DEFAULT;
如果没有在DropTarget添加DND.DROP_DEFAULT,则放开辅助键event.detail变成DND.DROP_MOVE。

在这里还可以改变currentDataType的值(但改后的值必须是dataTypes中的一个)。

l        dragLeave:鼠标离开对象时触发的事件(或拖放时按下ESC键)。一般用于拖放完成后释放一些资源

l        dropAccept:在完成拖放之前事件提供了最后一次定义数据类型的机会

l        drop:拖放完成后触发的事件。通过evet.data可获得由拖放源存放到全局变量中的数据。例如

if (TextTransfer.getInstance().isSupportedType(event.currentDataType))

       {…//读取event.data }

else if (FileTransfer.getInstance().isSupportedType(event. currentDataType))

       {…//读取event.data }


posted @ 2011-04-27 22:37  浪漫稻草人  阅读(397)  评论(0)    收藏  举报