本文属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 配置
1
2
3
4
5
6
7
8
9
10
11<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 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<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实现类即可。
- 拖拽的实现类
1
2
3
4
5
6
7
8
9
10package 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"; }
- 放的实现类
1
2
3
4
5
6
7
8
9
10
11package 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
重写方法即可。,重写后的实现如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61package 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内容请搜索靠谱客的其他文章。
发表评论 取消回复