首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

18.2 组件的拖拽功能(Drag and Drop)

操作系统中最常用的拖拽功能就是文件的移动复制,拖拽功能提高了软件的简用性。SWT也支持拖拽功能,不过编程实现比较繁琐。图18.1是实现拖拽的示意图,它首先要设定好拖拽源(DragSource)和能够接收的目标地(DropTarget),然后再设定一个运送拖拽数据的载体(Transfer),最后最繁琐的就是要给DragSource和DropTarget分别添加拖拽监听器,并根据拖拽途中的各种情况实现监听器的各方法。

   

图18.1  SWT拖拽实现的示意图             图18.2 拖拽实例一

下面给出一个拖拽实例,其运行效果如图18.2所示。图的左边是一个按钮,右边是一个文本框,可以将按钮文字拖拽到文本框中。如果按住Shift键拖拽,则为移动文字,结果是按钮变成空白,文字移到文本框。具体实现代码如下:

public class DragAndDrop1 {

         private TextTransfer textTransfer = TextTransfer.getInstance();

         private Button sourceText;

         private Text targetText;

         public static void main(String[] args) {

                   new DragAndDrop1().open();

         }

         private void open() {

                   final Display display = Display.getDefault();

                   final Shell shell = new Shell();

                   shell.setSize(300, 100);

                   // ---------创建窗口中的其他界面组件-------------

                   // 创建窗口组件

                   shell.setLayout(new FillLayout());

                   sourceText = new Button(shell, SWT.NONE);

                   sourceText.setText("HelloWolrd");

                   new Label(shell, SWT.NONE);// 分隔区

                   targetText = new Text(shell, SWT.BORDER);

                   // --------- 拖动设置-----------------

                   // 设置sourceText为拖拽源。允许数据被移动或复制

                   DragSource source = new DragSource(sourceText, DND.DROP_MOVE | DND.DROP_COPY);

                   source.setTransfer(new Transfer[] { textTransfer });// 设置传输载体为文本型

                   source.addDragListener(new MyDragSourceListener());

                   // 设置targetText为目标地

                   DropTarget target = new DropTarget(targetText, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT);

                   target.setTransfer(new Transfer[] { textTransfer });

                   target.addDropListener(new MyDropTargetListener());

                   // -----------------END------------------------

                   shell.layout();

                   shell.open();

                   while (!shell.isDisposed()) {

                            if (!display.readAndDispatch())

                                     display.sleep();

                   }

                   display.dispose();

         }

         private class MyDragSourceListener implements DragSourceListener {

                   // 判断是否允许拖拽。这里设定空字串时不允许拖拽

                   public void dragStart(DragSourceEvent event) {

                            Button button = getSource(event);// getSource是自定义方法

                            if (button.getText().trim().equals(""))

                                     event.doit = false;

                   }

                   // 自定义方法,取得拖拽源组件

                   private Button getSource(DragSourceEvent event) {

                            DragSource source = (DragSource) event.widget;

                            Button button = (Button) source.getControl();// 即sourceButton

                            return button;

                   }

                   // 设定需要用Transfer传输的数据

                   public void dragSetData(DragSourceEvent event) {

                            if (textTransfer.isSupportedType(event.dataType)) {// 是否支持拖拽的数据类型

                                     Button button = getSource(event);

                                     event.data = button.getText();

                            }

                   }

                   // 拖拽操作完成后执行此方法

                   public void dragFinished(DragSourceEvent event) {

                            if (event.detail == DND.DROP_MOVE) {// 如果是移动则删除sourceText中的文字

                                     Button button = getSource(event);

                                     button.setText("");

                            }

                   }

         }

         private class MyDropTargetListener implements DropTargetListener {

                   // 鼠标进入目标组件时调用此方法

                   public void dragEnter(DropTargetEvent event) {

                            // 默认为DND.DROP_DEFAULT,这里将其设为复制;按住Ctrl键为DND.DROP_COPY;按住Shift键为DND.DROP_MOVE。

                            if (event.detail == DND.DROP_DEFAULT)

                                     event.detail = DND.DROP_COPY;

                   }

// 鼠标在目标组件范围时会不断调用此方法。在此方法中主要是设置event.feedback,其可能值有:

//FEEDBACK_EXPAND 使当前光标下的项展开,以便拖拽到子项上,仅用于树型组件。

//FEEDBACK_INSERT_AFTER 在某项处于光标下之后显示一个插入标记,仅用于表格和树。

//FEEDBACK_INSERT_BEFORE 在某项处于当前光标下之前显示一个插入标记,仅用于表格和树。

//FEEDBACK_NONE 什么也不做.

//FEEDBACK_SCROLL 使目标组件可以滚动,以便可以拖到当前看不见的项上,仅用于表格和树。

//FEEDBACK_SELECT 使当前光标下的项被选中,仅用于表格和树。

                   public void dragOver(DropTargetEvent event) {

                            event.feedback = DND.FEEDBACK_NONE;

                   }

                   // 当按下或放开辅助按键(如Ctrl, Shift)时调用此方法

                   public void dragOperationChanged(DropTargetEvent event) {

                            if (event.detail == DND.DROP_DEFAULT)

                                     event.detail = DND.DROP_COPY;

                   }

                   // 当鼠标离开目标组件时会调用此方法

                   public void dragLeave(DropTargetEvent event) {}

                   // 在完成拖拽操作,执行drop方法之前调用此方法。

                   public void dropAccept(DropTargetEvent event) {}

                   // 在完成拖拽操作时最后调用的方法

                   public void drop(DropTargetEvent event) {

                            if (textTransfer.isSupportedType(event.currentDataType)) {

                                     String str = (String) event.data;// 取出传输数据

                                     DropTarget target = (DropTarget) event.widget;

                                     Text text = (Text) target.getControl();// 即targetText

                                     text.setText(str);

                            }

                   }

         }

}

程序说明:

  ● 虽然拖拽常用于表格和树,而本节是用按钮和文本框做实例,但基本原理和代码结构都一样。

  ● 可以设置多个拖拽目标地。一个组件既可以是拖拽源,也可以是拖拽目标地。

  ● event.detail= DND.DROP_NONE可以使拖拽失效。

  ● TextTransfer是Transfer的子类,查看Transfer的类层次结构可以找到更多的拖拽传输载体。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论