RCP:拖拽功能的实现 Drag and Drop
2014-03-14 15:46
711 查看
SWT中的拖拽是使用的org.eclipse.swt.dnd。
有三个需要密切注意的类:
1、DragSource
2、DropTarget
3、Transfer
DragSource封装了需要被拖拽的Control
DropTarget封装了拖拽的目标Control,即是拖拽终点的容器
Transfer是一个转换器,用于Java表示和平台指定的数据之间的相互转换
根据以上,我们可以揣测:
1、只有被DragSource封装了的Control对象才能被拖拽
2、只有被DropTarget封装了的Control对象才能被放置拖拽对象
3、同一次操作中,DragSource和DropTarget所定义的Transfer必须匹配
了解了这些基础,我们来看一个例子(该示例来自网络):
效果如图:
这只是实现了简单的控件和控件之间的拖拽。
现在我们来实现两个功能,从导航器或者操作系统里向编辑器中拖拽。
首先是导航器,大部分导航器使用了TreeViewer展示,org.eclipse.jface.viewers.StructuredViewer#addDragSupport方法为TreeViewer的Control添加了DragSource
即是创建DragSource的步骤已经预先完成了。
然后我们写一个编辑器,使用一个Text填充,Text部分源码如下:
注意红字部分,第一个LocalSelectionTransfer是为了让DropTarget能匹配导航器拖拽的部分内容,第二个FileTransfer是为了让其能匹配操作系统拖拽的文件。
以上即实现了拖拽功能。
这里提出一个问题,Text是如何识别到底一个拖拽进来的元素是否能够放置的呢?
这里,就需要看Transfer#validate的实现了。
如果被拖拽的元素能通过DropTarget所指定的任何一个Transfer的validate,就会被该Transfer所处理,然后转化为Java对象,应用到DropTarget封装的Control上去。
有三个需要密切注意的类:
1、DragSource
2、DropTarget
3、Transfer
DragSource封装了需要被拖拽的Control
DropTarget封装了拖拽的目标Control,即是拖拽终点的容器
Transfer是一个转换器,用于Java表示和平台指定的数据之间的相互转换
根据以上,我们可以揣测:
1、只有被DragSource封装了的Control对象才能被拖拽
2、只有被DropTarget封装了的Control对象才能被放置拖拽对象
3、同一次操作中,DragSource和DropTarget所定义的Transfer必须匹配
了解了这些基础,我们来看一个例子(该示例来自网络):
package z_test_project; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.*; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.*; public class DNDExample { public static void main(String[] args) { Shell shell = new Shell(); shell.setBackground(new Color(null, 200, 200, 200)); shell.setLayout(new GridLayout(2, false)); // Create the tree and some tree items final Tree tree = new Tree(shell, SWT.NONE); TreeItem item1 = new TreeItem(tree, SWT.NONE); item1.setText("Item 1"); TreeItem item2 = new TreeItem(tree, SWT.NONE); item2.setText("Item 2"); // Create the drag source on the tree DragSource ds = new DragSource(tree, DND.DROP_MOVE); ds.setTransfer(new Transfer[] {TextTransfer.getInstance()}); ds.addDragListener(new DragSourceAdapter() { public void dragSetData(DragSourceEvent event) { // Set the data to be the first selected item's text event.data = tree.getSelection()[0].getText(); } }); // Create the text field final Text text = new Text(shell, SWT.NONE); // Create the drop target on the text field DropTarget dt = new DropTarget(text, DND.DROP_MOVE); dt.setTransfer(new Transfer[] {TextTransfer.getInstance()}); dt.addDropListener(new DropTargetAdapter() { public void drop(DropTargetEvent event) { // Set the text field's text to the text being dropped text.setText((String)event.data); } }); shell.pack(); shell.open(); Display display = Display.getDefault(); while (!shell.isDisposed()) if (!display.readAndDispatch()) display.sleep(); display.dispose(); } }
效果如图:
这只是实现了简单的控件和控件之间的拖拽。
现在我们来实现两个功能,从导航器或者操作系统里向编辑器中拖拽。
首先是导航器,大部分导航器使用了TreeViewer展示,org.eclipse.jface.viewers.StructuredViewer#addDragSupport方法为TreeViewer的Control添加了DragSource
即是创建DragSource的步骤已经预先完成了。
题外:使用CNF生成的导航器必然会用到扩展点org.eclipse.ui.navigator.navigatorContent 其下有元素navigatorContent,其下又有元素dropAssitant 从命名可以看出,它指定的类是用来封装DropTarget和DropListener的 其内部实现有兴趣的自己阅读源码。 这部分是为了让导航器的内容可以在导航器内部拖拽。
然后我们写一个编辑器,使用一个Text填充,Text部分源码如下:
final Text text = new Text(composite, SWT.MULTI | SWT.BORDER); text.setText("测试页1"); DropTarget dropTarget = new DropTarget(text, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK | DND.DROP_TARGET_MOVE); dropTarget.setTransfer(new Transfer[] { LocalSelectionTransfer.getTransfer(), FileTransfer.getInstance() }); dropTarget.addDropListener(new DropTargetAdapter() { @Override public void drop(DropTargetEvent event) { text.setText(event.data == null ? null : event.data.toString()); } });
注意红字部分,第一个LocalSelectionTransfer是为了让DropTarget能匹配导航器拖拽的部分内容,第二个FileTransfer是为了让其能匹配操作系统拖拽的文件。
以上即实现了拖拽功能。
这里提出一个问题,Text是如何识别到底一个拖拽进来的元素是否能够放置的呢?
这里,就需要看Transfer#validate的实现了。
如果被拖拽的元素能通过DropTarget所指定的任何一个Transfer的validate,就会被该Transfer所处理,然后转化为Java对象,应用到DropTarget封装的Control上去。
相关文章推荐
- Unity3D-UGUI-drag and drop实现拖拽放下功能
- 让你的控件也具有拖拽(drag-and-drop)功能
- 在.NET中实现窗体控件的内容拖拽效果(Drag-and-Drop)
- 让你的控件也具有拖拽(drag-and-drop)功能
- Atitit。D&D drag&drop拖拽功能c#.net java swing的对比与实现总结
- 让你的控件也具有拖拽(drag-and-drop)功能
- Atitit。D&D drag&drop拖拽功能c#.net java swing的对比与实现总结
- 组件的拖拽功能(Drag and Drop)
- 分享一个HTML5的drag and drop API实现的图片拖拽分组效果
- EasyUI-treegrid-拖拽的实现(drag and drop)
- 让你的控件也具有拖拽(drag-and-drop)功能
- SWT 应用程序 实现的Drag and Drop(DND) 和 GEF 树上元素的拖拽
- 分享一个HTML5的drag and drop API实现的图片拖拽分组效果
- 分享一个HTML5的drag and drop API实现的图片拖拽分组效果
- Eclipse 拖拽功能(Drag and Drop)
- AsWing中自定义拖拽功能(Drag And Drop)
- 分享一个HTML5的drag and drop API实现的图片拖拽分组效果
- VC实现文件管理器拖拽(Drag-and-Drop)
- 转-让你的控件也具有拖拽(drag-and-drop)功能
- VC实现文件管理器拖拽(Drag-and-Drop)