概述
本文属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.CommonDragAdapterAssistant
和org.eclipse.ui.navigator.CommonDropAdapterAssistant
由CNF框架提供。
实现
引用Eclipse Explorer Viewer 的实现
Explorer Viewer 对Drag和Drop的实现类分别是org.eclipse.ui.navigator.resources.ResourceDragAdapterAssistant
和org.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";
}
此时启动项目,testProject01
和testProject02
中新建文件夹及文件,尝试拖动,会发现已经可以实现拖动了。
实现自己的规则
以上实现,尝试拖动发现,文件可以在不同的项目之间拖动,现假设需求为:不允许文件在项目间拖动
此需求只需要在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 实践(五)菜单及工具条定制
资料
- Common Navigator Framwork 参考资料
项目
- epx
最后
以上就是丰富火为你收集整理的Common Navigator Framework 实践(三)文件拖拽控制分析实现效果系列文章资料项目的全部内容,希望文章能够帮你解决Common Navigator Framework 实践(三)文件拖拽控制分析实现效果系列文章资料项目所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复