JavaFX之Drag And Drop拖放操作

22 篇文章 30 订阅

  声明:   本博客文章原创类别的均为个人原创,版权所有。转载请注明出处: http://blog.csdn.net/ml3947 (看到有网站直接copy不加链接,当然我的个人博客文章目前都是从我的CSDN博客转移上去的)。


  大家好,新的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下载栏目效率太低,就传到其他地方去。

------------------------------------------------------------------------------------------

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值