大家好,新的JavaFX的教程又到来了。
是不是很多程序都有拖动文件到程序里的功能?有没有感觉拖放操作很cool?我们的JavaFX当然也支持这样的操作。
在JavaFX中,我们不仅可以从一个控件拖动内容到另外一个控件,还可以从系统拖动文件到JavaFX的控件,甚至还可以从一个JavaFX程序中拖动内容到另外一个JavaFX程序中。
看起来不错吧?我们下面将会讲解在JavaFX中的拖放操作。
首先,打个小广告。本人的个人博客地址: http://www.wjfxgame.com
目前本人的JavaFX示例都可以在个人博客上面在线运行(除了部分)。虽然因为笔记本数据丢失,数量不多。不过本人也一直在编写中(由于在开发JavaFX游戏引擎,可能速度不会很快)。
本篇教程的示例地址: 点击
从Drag Me的标签拖动到 Drop On Me标签上。
从本地,拖动一个图片 到 drag a image to this的标签下面,可以显示你拖动的图片。
从本地,拖动一个文本文件 到 drag a txt to this的标签下面,可以显示你拖动的文本的内容(因为编码问题可能乱码,可以使用UTF-8等编码的文本)。
截图:
在JavaFX中关于拖放操作,可以设置这么几种事件监听器。
setOnDragDetected(new EventHandler<MouseEvent>());
当你从一个Node上进行拖动的时候,会检测到拖动操作,将会执行这个EventHandler。
setOnDragEntered(new EventHandler<DragEvent>());
当你拖动到目标控件的时候,会执行这个事件回调。
setOnDragExited(new EventHandler<DragEvent>());
当你拖动移出目标控件的时候,执行这个操作。
setOnDragOver(new EventHandler<DragEvent>());
当你拖动到目标上方的时候,会不停的执行。
setOnDragDropped(new EventHandler<DragEvent>());
当你拖动到目标并松开鼠标的时候,执行这个DragDropped事件。
setOnDragDone(new EventHandler<DragEvent>());
当你拖动并松手的时候,执行Drag完成操作。
这里要注意的是,首先执行拖动,拖动到目标控件的时候,会首先执行DragEnter,这个只执行一遍。然后当你停留在目标控件上方的时候,会不停的指定DragOver操作。
下面我们来看看示例中的代码:
- m_drag.setOnDragDetected(new EventHandler<MouseEvent>() {
- @Override
- public void handle(MouseEvent event) {
- Dragboard dragboard = m_drag.startDragAndDrop(TransferMode.ANY);
- ClipboardContent content = new ClipboardContent();
- content.putString(m_drag.getText());
- dragboard.setContent(content);
- }
- });
- m_drop.setOnDragEntered(new EventHandler<DragEvent>() {
- @Override
- public void handle(DragEvent event) {
- m_drop.setTextFill(Color.RED);
- }
- });
- m_drop.setOnDragExited(new EventHandler<DragEvent>() {
- @Override
- public void handle(DragEvent event) {
- m_drop.setTextFill(Color.BLACK);
- }
- });
- m_drop.setOnDragOver(new EventHandler<DragEvent>() {
- @Override
- public void handle(DragEvent event) {
- if (event.getGestureSource() != m_drop && event.getDragboard().hasString()) {
- event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
- }
- }
- });
- m_drop.setOnDragDropped(new EventHandler<DragEvent>() {
- @Override
- public void handle(DragEvent event) {
- Dragboard dragboard = event.getDragboard();
- m_drop.setText(dragboard.getString());
- }
- });
- m_drag.setOnDragDone(new EventHandler<DragEvent>() {
- @Override
- public void handle(DragEvent event) {
- m_drag.setText("");
- }
- });
其中m_drag是Drag Me标签Label。m_drop是Drop on Me标签Label。
我们在检测到拖动m_drag标签的时候,使用了一个Dragboard,俗称"拖板"(...), 当然不能这样称呼,但是很明显,它就类似于ClipBoard剪切板。我们将拖动要传送的数据使用ClipboardContent设置到Dragboard上。
其他的就是比较简单的,当拖动到m_drop上面的时候,改变m_drop的颜色。
在DragOver的时候 通过event.acceptTransferModes(TransferMode.ANY);来设置接收数据的类型。
在Drag松开的时候,通过获取Dragboard的数据,来设置到标签上。
上面是JavaFX中 控件与控件之间拖动数据的示例。当然很多处理不得当,只是为了演示所有的拖动方法,所以才将每个事件都使用到。
下面来看看拖动文件的:
- m_imageView.setOnDragOver(new EventHandler<DragEvent>() {
- @Override
- public void handle(DragEvent event) {
- if (event.getGestureSource() != m_imageView) {
- event.acceptTransferModes(TransferMode.ANY);
- }
- }
- });
- m_imageView.setOnDragDropped(new EventHandler<DragEvent>() {
- @Override
- public void handle(DragEvent event) {
- Dragboard dragboard = event.getDragboard();
- List<File> files = dragboard.getFiles();
- if(files.size() > 0){
- try {
- m_imageView.setImage(new Image(new FileInputStream(files.get(0))));
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
- }
- });
这里只有一个DragOver和DragDropped。
松手之后,同样通过 Dragboard获取拖动的文件列表,我们这里将拖动到的第一个文件当作数据流创建图片并设置到imageView中。
这里的操作比较简单,其实可以做更为复杂的判断。
文本也是相同的:
- m_textArea.setOnDragOver(new EventHandler<DragEvent>() {
- @Override
- public void handle(DragEvent event) {
- if (event.getGestureSource() != m_imageView) {
- event.acceptTransferModes(TransferMode.ANY);
- }
- }
- });
- m_textArea.setOnDragDropped(new EventHandler<DragEvent>() {
- @Override
- public void handle(DragEvent event) {
- Dragboard dragboard = event.getDragboard();
- List<File> files = dragboard.getFiles();
- if(files.size() > 0){
- m_textArea.setText(FileTools.readFile(files.get(0)));
- }
- }
- });
是不是很简单,当拖动操作在JavaFX程序中流行起来后,想一想我们可以从这个JavaFX程序拖动到另外一个JavaFX程序中,就会觉得很兴奋,或许会因此出现很多意想不到的应用(当然,前提是JavaFX能够被大家认可,广泛传播)。
考虑到大家copy粘贴源代码修改看效果也不方便,以后本人的示例工程全部打包上传到CSDN下载栏目中,并且无需积分。
本文章示例项目下载地址: http://download.csdn.net/detail/ml3947/5307918
转载请注明出处: http://blog.csdn.net/ml3947
-----------------------------------------------------------------------------------------
...上传资源后,得了很久才显示出来。要是CSDN下载栏目效率太低,就传到其他地方去。