DOC-07-07 拖放操作

在本章中你将学习如何在JavaFX程序中实现拖放特性,包括在拖放手势中会用到哪些对象、会传输什么类型的数据以及会产生哪些事件。

本文档也包含一些代码样例来展示用到的API和说明材料。

拖放操作的对象和数据类型

拖放操作是两个对象之间的数据传输:手势源和手势目标。手势源和手势目标可以是如下对象:

● 节点(Node)

● 场景(Scene)

手势源和手势目标可以属于同一个JavaFX程序或者是两个不同的JavaFX或Java客户端程序。此外,拖放手势也可以在JavaFX程序和第三方(本地)程序之间实现,例如Windows资源管理器或者是桌面。

拖放手势是这样发生的:用户在手势源处按下了鼠标按键,然后拖动鼠标并在手势目标处松开鼠标按键。在拖放数据时用户会得到可视化的反馈,它会表示哪些位置不接受数据,而当鼠标移到可接受数据的目标上时则会提示用户在哪里放下数据。

数据通过拖放板(Dragboard)来传输,Dragboard与系统剪贴板(Clipboard)的接口一样,但只能用来在拖放时进行数据传输。

在拖放手势期间可传输多种数据,例如文本、图像、URL、文件、字节、字符串等。

javafx.scene.input.DragEvent类是实现拖放手势的基础类。要了解特定方法或者javafx.scene.input包中的其它类的使用,请参考API文档。

传输模式

传输模式定义了手势源和手势目标之间的传输类型。可用的传输模式包括COPY、MOVE和LINK。

手势源会报告所支持的传输模式。手势目标可接受一种或多种传输模式。系统根据用户按下的键盘修饰符类从手势源和手势目标均支持的传输模式中选择合适的传输模式。

实现基本的拖放手势

你将通过使用HelloDragAndDrop样例程序来学习如何实现基本的拖放功能。手势源和手势目标是两个text节点,如例7-1所示。

例7-1

 

在手势源上开始拖放拖放手势

拖放拖放动作只能通过在手势源的DRAG_DETECTED事件处理器(Event Handler)中调用startDragAndDrop方法来开启。手势源所支持的传输模式也是在这里定义的,传输的数据也会被放到Dragboard上。

请查看例7-2中onDragDetected Event Handler的实现。

例7-2

startDragAndDrop方法以手势源支持的传输模式为参数,你可以传入可用的传输模式的任意组合。传入TransferMode.COPY表示该手势源仅支持复制,不支持移动或引用。

在手势目标上处理DRAG_OVER事件

在拖放拖放手势开始以后,鼠标经过的任何节点或者场景都是接收数据的潜在目标。你可以通过实现DRAG_OVER Event Handler来指定由哪个对象来接收数据。

请注意DRAG_OVER Event Handler的重要性。想要成功地完成一次拖放拖放操作,必须要实现DRAG_OVER Event Handler,它调用了事件的acceptTransferModes(TransferMode …)方法,传入了手势目标可接受的传输模式。如果手势源都不支持传入的传输模式,则表示该潜在目标是不适合该拖放手势的。

注意在决定是否接受该事件时必须要顾及到Dragborad上的可用数据类型。要访问Dragborad上的数据,请使用event.getDragboard()方法。

例7-3展示了DRAG_OVEREvent Handler的实现。

例7-3

通过手势目标给予可视化反馈

在拖放手势执行期间,当鼠标指针经过与该拖放手势匹配的潜在目标上方时,该潜在目标一般会改变外观来提示用户可把数据放下。

当拖放手势进入潜在手势目标的边缘时,该目标会收到DRAG_ENTERED事件。当拖放手势离开潜在手势目标的边缘时,该目标会收到DRAG_EXITED事件。你可以通过DRAG_ENTERED和DRAG_EXITED的Event Handler来改变手势目标的外观以便给用户提供可视化反馈。

例7-4展示了如何通过改变文本的颜色来实现可视化反馈。

例7-4

请注意校验Dragboard的内容的重要性。手势目标只会在Dragboard中包含有合适格式的数据时改变外观,在本例中是一个字符串数据。

例7-5展示了DRAG_EXITEDEvent Handler的实现,在该实现中恢复了文本的原始外观。

例7-5

 在手势目标上处理DRAG_DROPPED事件

当在手势目标(该目标接受了前面的DRAG_OVER事件且传输模式受手势源支持)上松开鼠标按键时,会收到DRAG_DROPPED事件。在DRAG_DROOPEDEvent Handler中,你需要调用事件的setDropCompleted(Boolean)方法来完成该事件。否则,该手势会被认为未成功完成。

请参考例7-6中的DRAG_DROPPED Event Handler的实现。

例7-6

在手势源上处理DRAG_DONE事件

在拖放手势完成以后,会发送DRAG_DONE事件到手势源来通知该手势是如何完成的。在DRAG_DONEEvent Handler中,通过调用事件的getTransferMode方法来获取传输模式。如果传输模式是NULL表示数据传输未发生。如果传输模式是MOVE则清空掉手势源上的数据,如例7-7所示。

例7-7

 

拖放自定义数据

类似的,你可以在自定义数据上实现拖放手势。定义自定义数据类型如例7-8所示。

例7-8

当把自定义数据放入Dragboard上时需要指定数据类型。请注意,该数据必须是可序列化的。

当从Dragboard上读取数据时需要进行合适的数据转换。

程序文件

源码

HelloDragAndDrop.java

NetBeans工程

HelloDragAndDrop.zip

打赏一下
支付宝
微信
除非注明,博客文章均为原创,转载请标明文章地址
本文地址: http://www.javafxchina.net/blog/2015/09/doc0707-drag-drop/
百度已收录