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

最近学习Eclipse,发现当前市场上的教程对SWT控件的拖放都说得词不达意,无法理解,包括质量较高的《Java开发利器:Eclipse SWT/JFace 核心应用》。自己花了很多时间研究才搞明白,心得如下:

SWT中有关拖放操作的类都在org..eclipse.swt.dnd包中。实现拖放首先需要一个DragSoruce类,也就是被拖放的对象,一个DropTarget,也就是要放的目的地对象,还要在两者之间传输拖放对象携带的数据,用Transfar类来定义。在拖的过程中将Java的数据转化为本地保存的全局变量数据,然后在放的过程中,再从本地保存的全局变量中将数据取出。

DragSource

拖放源是一个类,真正拖放的是在创建时要绑定的控件,例如

Table t= new Table(shell,SWT.NONE)

DragSource source=new DragSource(t,DND.Drop_MOVE|DND>DROP_COPY)

同一widget只能绑定在一个DragSource或DropTarget上。创建拖放源的第二个参数是拖放过程中支持的操作类型,它决定了拖到目标上。DND类中定义了专用于拖放的一些常量。

操作常量

说明

DROP_COPY

The item is copied when dragged in or out of this control.

DROP_MOVE

The item is moved from its current location to wherever it’s dropped.

DROP_LINK

Dropping the item creates a link back to the original.

DROP_NONE

Nothing happens when the item is dropped.

上例中表示允许移动和复制。

拖放源创建后要定义拖放过程中需传递的数据类型,即将什么样的数据格式存放在本地系统的全局变量中;使用DragSource.setTransfer(Transfer[] transferAgents)方法完成数据的定义,其参数是一个Transfer实例(一般是其子类的实例)构成的数组例如:

dragSource.setTransfer(new Transfer[] { TextTransfer.getInstance() });//只传递字符串

或允许传递两种数据类型:

Source.setTransfer(new Transfer[] { TextTransfer.getInstance(), FileTransfer.getInstance()});

最后要添加拖放事件处理方法,即:dragSource.addDragListener(new DragSourceListener)或使用DragSourceAdapter。该监听器包含了3个事件:

a)       dragStart(DragSourceEvent):开始拖动一瞬间发生;一般用于判断是否开始拖动。如不允许拖动则令event的doit属性为false。例如以表格为拖放源时要判断表格有选中的行时才能开始拖动。

b)       dragSetData(DragSourceEvent):释放的操作已执行时触发。该方法须设置要drop的数据,起始就是给event的data域赋值。event的dataType域规定了要设置的数据类型,如果拖放源在创建时绑定Transfer时允许传递多种数据类型(也就是绑定了多种Transfer),则需要在这里根据event.dataType来确定将什么样格式的数据放入data域中,例如:

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

       {…//event.data赋值字符串}

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

       {…//event.data赋值字符串数组}

c)       dragDinished(DragSourceEvent):完成拖放后的事件,一般是一些清理工作,例如如果拖放被定义成移动,在要在拖动源中删除已移动的数据。通过event.detail域可以得知目标对象进行了什么操作,这些操作包括

                                i.            DND.DROP_COPY: 目标对象复制了数据

                               ii.            DND.DROP_MOVE: 目标对象剪切了数据,需要删除原来的数据

                              iii.            DND.DROP_LINK: 目的对象创建了快捷方式

                             iv.            DND.DROP_TARGED_MOVE:目的对象改变了数据的位置,通常用于移动文件

不同的操作对应不同的鼠标形状。拖放时到底实现的是什么操作,需要在目标控件的监听器中确定(见后)。

Transfer

SWT使用Transfer类实现拖动源到释放目的地在数据类型上的沟通:移动的数据必须是双方都可理解的格式。Transfer存在的理由是需要将拖放的数据保存在本地操作系统中作为全局变量,因此需要有一个实现java数据到本地数据格式之间转换的机制。

Transfer的每一个子类都代表特定的数据类型,而且知道如何将数据在java和本地操作系统之间转换,包括文本、文件和RTF格式的文本,如果这些数据类型不满足要求,用户还可以自定义Transfer的子类(参考org.eclipse.swt.dnd.Transfer 和org.eclipse.swt.dnd.ByteArrayTransfe的文档)。就应用而言可以把Transfer实例看成一个代表特定数据类型的黑箱。每个子类都有一个静态工厂方法getInstance()来创建一个实例,我们只需将它作为参数来指定要传递的数据类型,无须调用它的其他方法。实质上,通过Transfer,SWT调用javaToNative()和nativeToJava()来转换数据(在需要时)。通用的Transfer子类有:

l        FileTransfer:名义上用于传递一个或多个文件,实际上是字符串数组(可理解为多个文件路径储存在字符串数组中);

l        TextTransfer:传递字符串;

l        RTFTransfer:传统rich text formatting格式的字符串

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