SWT 应用程序 实现的Drag and Drop(DND) 和 GEF 树上元素的拖拽

9 篇文章 0 订阅
9 篇文章 0 订阅

Drag and drop 提供了一种在应用程序-应用程序中重新利用或者是转换数据的方法。本文讲述了如何在一个SWT应用程序中使用Drag 和 Drop机制和如何使用剪贴版转换数据。

Drag and Drop Overview
举一个简单的使用Drag and Dorp的例子:从一个table中拖动一个item到另一个table。

右边的table列出了可供选择的商品,左侧是我们的购物车。要购买什么,我可以简单的通过选择右侧table中的一个item,然后把它drap到左侧然后drap(中文直接称为”拖动”)。当我松开鼠标左键,该商品就自动添加到购物车中了。这个过程中有个数据转换,右侧的称为drag source,我们的购物车称为drop target。当我拖动鼠标到一个drop target上,会有相应的反映。首先,鼠标改变了,告诉我们这是一个可以drop的区域,同时鼠标的改变还告诉我们操作的类型。其次,选中的item会高亮显示。(这称为”drag under effect”)。
要实现Drag and Drop,我们分四个部分来讲:
1.DragSource。
2。Droptarget。
3。Clipboard。
4。Transfer。
Drag Source:
一个drag source 是Drag and Drop中的数据提供者,同时也是Drag and Drop操作的发起者。数据的提供者可以是在同一个widget,或者是同一个程序的不同的widget中,甚至是不同的应用程序中。例如,你可以从你程序中拖动一个文本,然后放到一个email程序中,或者是你可以从一个tree中拖动一个item然后放到其它tree,作为一个不同的节点。
让我们先看看一个简单的定义一个drag source的例子。这个例子中我们演示如何从一个label widget拖动文本。
1 import org.eclipse.swt.dnd.*;
2
3 // 把一个Label作为一个Drag Source
4 final Label dragLabel = new Label(shell, SWT.BORDER);
5 dragLabel.setText(“text to be transferred”);
6
7 // 允许从这个drag source中拷贝和移动数据。
8 int operations = DND.DROP_MOVE | DND.DROP_COPY;
9 DragSource source = new DragSource(dragLabel, operations);
10
11 // Provide data in Text format
12 Transfer[] types = new Transfer[] {TextTransfer.getInstance()};
13 source.setTransfer(types);
14
15 source.addDragListener(new DragSourceListener() {
16 public void dragStart(DragSourceEvent event) {
17 // 只有在label中有文本的时候才开始drag
18 // label - 这个文本就是将drop到目标上的文本
19 if (dragLabel.getText().length() == 0) {
20 event.doit = false;
21 }
22 }
23 public void dragSetData(DragSourceEvent event) {
24 // 提供请求类型的数据.
25 if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
26 event.data = dragLabel.getText();
27 }
28 }
29 public void dragFinished(DragSourceEvent event) {
30 //
31 // 如果是移动操作,就从source上移出数据。
32 if (event.detail == DND.DROP_MOVE)
33 dragLabel.setText(“”);
34 }
35 }
36 });
下面分析下上面的代码:
1行:SWT的所有的drag和drop类都是定义在org.eclipse.swt.dnd包中。
3~5行:创建一个widget。我们的例子使用了一个label。
7~9行:为了使一个widget称为一个drag source,我们必须创建一个org.eclipse.swt.dnd.DragSource对象。DragSource 构造器需要两个参数,一个是指定widget,第二个是允许的操作,允许的操作决定了drop target实际的动作。运行的只可以是:DND.DROP_COPY, DND.DROP_MOVE 或者是 DND.DROP_LINK它们可以是OR的关系。我们的例子中允许move和copy操作。
11~13行:要完成定义drag source的工作,你必须自动drap and drop之间传递的数据的类型。一个数据类型是通过org.eclipse.swt.dnd.Transfer的子类来定义的,例如TextTransfer或者是FileTransfer。更多的细节请查看后面的文章。一个drag source可以提供不只一种格式的数据,然而,当请求的时候必须提供相应的数据格式。我们的例子中,用户可以从label中drag文本。

1.概况介绍
Drag&Drop(后简称DND)可以增强程序的可操作性,提高程序的可视化操作能力。从而提高程序的吸引力。

    在SWT下实现DND主要涉及三个类和两个接口以及两个事件类:
    类:        
            org.eclipse.swt.dnd.DragSource 
            org.eclipse.swt.dnd.DropTarget 
            org.eclipse.swt.dnd.Transfer

    接口:    
            org.eclipse.swt.dnd.DragSourceListener
            org.eclipse.swt.dnd.DropTargetListener

    事件类:
            org.eclipse.swt.dnd.DropTargetEvent
            org.eclipse.swt.dnd.DragSourceEvent


    我学习的资料:
          1. 《SWT/JFace in Action》
                    http://chinateam.myrice.com/matrix/Java/j2se/java_ide/Eclipse%20in%20Action.pdf
          2.《Guide to SWT and JFace》
                    http://www.fixdown.com/soft/21244.htm
          3.  Drag and Drop                         
                    http://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html#_dt10D
          4.  Drag and Drop in the Eclipse UI
                    http://www.eclipse.org/articles/Article-Workbench-DND/drag_drop.html
    相比起来,在对DND的说明方面,后两个文献要详尽的多。如果大家的英文比较好,我建议还是直接看后两个文献。

2.Drag and Drop的实现过程
Drag&Drop由两个步骤组成:Drag和Drop过程。
2.1 Drag过程
要实现Drag过程的步骤如下。

1.确定DND操作源组件,并声称相应的DragSource。
DragSource类和后面要提到的DropTarget都属于封装类,构造函数的参数表均为 (Control control, int style)。
通过将一个Control传递给DragSource的构造函数,一个组件可以被定为一个DND操作源,构造函数的第二个参数表示DND操作源所允许的操作方式。需要注意的是,不能将一个组件指定为多个DND操作源,否则会产生SWTError。换句话说,一个组件只能为DND操作提供一类数据。
上面涉及到的style参数决定了DND操作接收者可以对传送过去的数据采取的操作方式,style的值可以是 DND.DROP_COPY, DND.DROP_MOVE 和DND.DROP_LINK 或者是三者中的按位或的结果。注意,这三个值是org.eclipse.swt.dnd.DND的静态成员。

2.确定DND操作传输的数据的类型

3.设置监听器,控制Drag过程的运作


在gef树上自身实现元素的拖拽,只需要安装TreeContainerEditPolicy这个policy并且实现
这样两个方法就可以了。

@Override(当元素不在同一个文件夹下进行拖拽,则调用这个方法)
protected Command getAddCommand(ChangeBoundsRequest request)

@Override(如果元素在同一个文件夹下进行拖拽,则调用这个方法)
protected Command getMoveChildrenCommand(ChangeBoundsRequest request)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值