Common Navigator Framework 实践(三)文件拖拽控制

本文属CNF系列汇总中的第三篇,主要介绍自定义导航中如何实现文件拖拽功能。

分析

CNF 提供了标准的拖拽操作支持——Drag and Drop Support,Drag and Drop Support 指的就是节点的拖放操作。

CNF 实现拖拽操作需要实现两个扩展点

  • Drag 扩展点为 dragAssistant
    这个扩展点提供“拖”操作的支持,位于 org.eclipse.ui.navigator.viewer 扩展点下。
    dragAssistant有class和viewerId两个属性,class属性指定了drag操作的实现类,该类必须继承org.eclipse.ui.navigator.CommonDragAdapterAssistant。viewerId 用于指定该拖动实现作用于哪个导航视图(org.eclipse.ui.navigator.viewer)。

  • Drop 扩展点dropAssistant,这个扩展点处理“放”的功能,位于 org.eclipse.ui.navigator.navigatorContent下。设计在 navigatorContent 里面声明,大概是因为 Drop 操作不能在不同的 navigatorContent 之间共享的缘故。
    dropAssistant也有两个属性,分别是id和class,分别为“放”操作的实现类ID和实现类,放的实现类必须继承org.eclipse.ui.navigator.CommonDropAdapterAssistant

其中org.eclipse.ui.navigator.CommonDragAdapterAssistantorg.eclipse.ui.navigator.CommonDropAdapterAssistant 由CNF框架提供。

实现

引用Eclipse Explorer Viewer 的实现

Explorer Viewer 对Drag和Drop的实现类分别是org.eclipse.ui.navigator.resources.ResourceDragAdapterAssistantorg.eclipse.ui.navigator.resources.ResourceDropAdapterAssistant。以下我们引用这两个实现,使得自定义导航拥有与Eclipse 导航同样的拖拽功能。

  • Drag 的 plugin.xml 配置
<extension
         point="org.eclipse.ui.navigator.viewer">
      <viewer viewerId="com.xzbd.views.MainNavigator">
     <!-- …… 篇幅问题省去其他代码 -->
      <dragAssistant
            class="com.xzbd.navigator.dnd.DragAdapterAssistant"
            viewerId="com.xzbd.views.MainNavigator">
      </dragAssistant> 
          
   </extension>
  • Drop 的 plugin.xml 配置
<extension
         point="org.eclipse.ui.navigator.navigatorContent">
      <navigatorContent
            activeByDefault="true"
            id="com.xzbd.epx.MainNavigatorContent"
            name="mainNavigatorContent"
            labelProvider="com.xzbd.navigator.provider.MainLabelProvider"
            contentProvider="com.xzbd.navigator.provider.MainContentProvider"
            priority="normal">
      <!-- 省略triggerPoints和possibleChildren -->
	         
	  <!-- 新建文件向导 省略-->
	  <!-- 新建文件夹向导 省略-->
         <dropAssistant
               class="com.xzbd.navigator.dnd.DropAdapterAssistant"
               id="com.xzbd.navigator.dnd.DropAdapterAssistant">
            <possibleDropTargets></possibleDropTargets>
         </dropAssistant>
      </navigatorContent>
      <!-- 自定义导航 省略-->
      <!-- 编辑按钮组 省略-->
      <!-- 新建按钮组 省略 -->
   </extension>

注意dropAssistant标签的ID属性是自定义的。

拖拽和放的实现类方法直接继承Eclipse实现类即可。

  • 拖拽的实现类
package com.xzbd.navigator.dnd;

import org.eclipse.ui.navigator.resources.ResourceDragAdapterAssistant;

public class DragAdapterAssistant extends ResourceDragAdapterAssistant{
	public static final String ID = "com.xzbd.navigator.dnd.DragAdapterAssistant";
	
}

  • 放的实现类
package com.xzbd.navigator.dnd;

import org.eclipse.ui.navigator.resources.ResourceDropAdapterAssistant;

public class DropAdapterAssistant extends ResourceDropAdapterAssistant {

	public static final String ID = "com.xzbd.navigator.dnd.DropAdapterAssistant";

}

此时启动项目,testProject01testProject02中新建文件夹及文件,尝试拖动,会发现已经可以实现拖动了。

实现自己的规则

以上实现,尝试拖动发现,文件可以在不同的项目之间拖动,现假设需求为:不允许文件在项目间拖动

此需求只需要在com.xzbd.navigator.dnd.DropAdapterAssistant重写方法即可。,重写后的实现如下

package com.xzbd.navigator.dnd;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.ui.navigator.CommonDropAdapter;
import org.eclipse.ui.navigator.resources.ResourceDropAdapterAssistant;

import com.xzbd.utils.AppPrinter;
import com.xzbd.utils.WorkbenchUtil;


public class DropAdapterAssistant extends ResourceDropAdapterAssistant {

	public static final String ID = "com.xzbd.navigator.dnd.DropAdapterAssistant";

	@Override
	public IStatus handleDrop(CommonDropAdapter aDropAdapter, DropTargetEvent aDropTargetEvent, Object destTarget) {
		
		// 获取当前拖动的数据
		Object data = aDropTargetEvent.data;
		if(Objects.isNull(data)) {
			return Status.CANCEL_STATUS;
		}
		
		// 如果不是类型不是 TreeSelection ,因为导航视图的资源实现自 TreeSelection
		if(!(data instanceof TreeSelection)) {
			return Status.CANCEL_STATUS;
		}
		TreeSelection treeSelection = (TreeSelection)data;
		// 所有拖动资源的项目名
		Set<String> projectNames = new HashSet<>();
		Iterator<?> iterator = treeSelection.iterator();
		while (iterator.hasNext()) {
			String pName = WorkbenchUtil.getProjectName(iterator.next());
			if(pName != null && !pName.isBlank()) {
				projectNames.add(pName);
			}
		}
		// 获取目标资源所在的项目名
		String destProjectName = WorkbenchUtil.getProjectName(destTarget);
		// 如果有一个被拖文件与目标不是在同一个项目,则取消整个拖拽操作
		for(String pName : projectNames) {
			if(!pName.equals(destProjectName)) {
				AppPrinter.println("资源与目标不是同一个项目,取消拖拽" );
				return Status.CANCEL_STATUS;
			}
		}
		
		return super.handleDrop(aDropAdapter, aDropTargetEvent, destTarget);

	}
}

如此就实现了资源拖拽的控制需求:不允许文件在项目间拖动。当触发资源在项目间拖动时,软件控制台将打印 资源与目标不是同一个项目,取消拖拽

在这里插入图片描述

效果

拖放效果无法截图展示,请前往项目地址拉项目,自己尝试。

系列文章

CNF系列汇总
Common Navigator Framework 实践(一)自定义导航
Common Navigator Framework 实践(二)菜单扩展
Common Navigator Framework 实践(三)文件拖拽控制
Common Navigator Framework 实践(四)文件过滤
Common Navigator Framework 实践(五)菜单及工具条定制

资料

项目

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值