RCP:拖拽功能的实现 Drag and Drop

简介: SWT中的拖拽是使用的org.eclipse.swt.dnd。 有三个需要密切注意的类: 1、DragSource 2、DropTarget 3、Transfer   DragSource封装了需要被拖拽的Control DropTarget封装了拖拽的目标Control,即是拖拽终点...

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必须匹配

 

了解了这些基础,我们来看一个例子(该示例来自网络):

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上去。

 

 

 

 

 

 

 

 

目录
相关文章
|
8月前
|
API
ant.design Table组件点击一个选项框却把所有选项都选中了
ant.design Table组件点击一个选项框却把所有选项都选中了
88 0
ant.design Table组件点击一个选项框却把所有选项都选中了
在Qt quick5.10-qml中使用drag and drop进行拖拽,及qml拖拽的Bug
在Qt quick5.10-qml中使用drag and drop进行拖拽,及qml拖拽的Bug
Qt实现鼠标拖放(drag/drop)
Qt实现鼠标拖放(drag/drop)
193 0
Silverlight & Blend动画设计系列八:拖放(Drag-Drop)操作与拖放行为(DragBehavior)
原文:Silverlight & Blend动画设计系列八:拖放(Drag-Drop)操作与拖放行为(DragBehavior)   在Silverlight中自身并没有提供拖放功能的相关实现,要实现拖放功能得借助其事件支持(MouseLeftButtonDown、MouseLeftButtonUp和MouseMove)来完成,实际应用中我们可以通过行为(Behavior)特性将拖放操作封装为行为,这样可达到代码复用的效果。
1045 0
|
图形学 异构计算

热门文章

最新文章