服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 开发工具 > 查看文档

在rcp中实现用托拽打开editor

    工作台窗口的editor区域默认是显示的,而且它支持拖拽操作。在eclipse里面,把一个文件拖到editor区域,就会自动打开该文件的editor.该特性是在iworkbenchwindowconfigurer 中设置。
 
    在password gate中,当拖动password gate view中的一个group 或者 service到editor区域,会在editor显示该项的属性。
 
    要实现此特性,有四部分是必须的。
 
    1     实现必要的transfer类型,而且定义editor要支持哪些类型。在password gate中,transfer是localselectiontransfer.transfer用来进行数据的序列化,它可以支持在同一个程序,或不同程序间拖拽。
 
    2        因为在拖拽传递的过程中editor input 要实现序列化,所以要实现ipersistableelement接口。
 
    3        加入一个释放适配器,当一个元素被扔到editor区域,它可以知道如何进行操作,其实就是打开该元素的editor.
 
    4        使password view能够进行拖操作,它要提供供拖的元素。
 
    下面进行代码实现。
 
    在rcp的workbenchwindowadvisor. prewindowopen中定义要求editor area支持的拖入对象的类型,以及打开相应editor的事件。
 
    applicationworkbenchwindowadvisor.prewindowopen()
01 public void prewindowopen() {
02     ......
03     configurer.addeditorareatransfer(localselectiontransfer.getinstance());
04     configurer.configureeditorareadroplistener(new editorareadropadapter(
05         configurer.getwindow())); 
06     }

    row 03定义了editor area支持的transfer为localselectiontransfer, localselectiontransfer为自己实现的传输介质类。row 04定义了对拖入editor area的对象的处理方法。editorareadropadapter实现了droptargetlistener接口,用来监听editor area中的drop事件,它会打开拖入editor area的对象所对应的editor,如果同时拖入多个对象,它会打开每个对象对应的editor.

 
editorareadropadapter.java
01 public class editorareadropadapter extends droptargetadapter {
02   private iworkbenchwindow window;
03   
04   public editorareadropadapter(iworkbenchwindow window) {
05     this.window = window;
06   }
07 
08   public void dragenter(droptargetevent event) {
09     // always indicate a copy
10     event.detail = dnd.drop_copy;
11   }
12 
13   public void dragoperationchanged(droptargetevent event) {
14     // always indicate a copy
15     event.detail = dnd.drop_copy;
16   }
17 
18   public void drop(final droptargetevent event) {
19     display d = window.getshell().getdisplay();
20     final iworkbenchpage page = window.getactivepage();
21     if (page != null) {
22       d.asyncexec(new runnable() {
23         public void run() {
24           asyncdrop(event, page);
25         }
26       });
27     }
28   }
29 
30   private void asyncdrop(droptargetevent event, iworkbenchpage page) {
31     if (localselectiontransfer.getinstance().issupportedtype(
32         event.currentdatatype)) {
33       structuredselection selection = (structuredselection) event.data;
34       for (iterator iter = selection.iterator(); iter.hasnext();) {
35         object o = iter.next();
36         if (o instanceof record) {
37           ieditorinput input = new recordeditorinput((record) o);
38           try {
39             page.openeditor(input, recordeditor.id);
40           } catch (exception e) {
41             pwdgateplugin.log("open ediotr recordeditor", e);
42           }
43         } else if (o instanceof group) {
44           ieditorinput input = new groupeditorinput((group) o);
45           try {
46             page.openeditor(input, groupeditor.id);
47           } catch (partinitexception e) {
48             pwdgateplugin.log("open ediotr groupeditor", e);
49           }
50         }
51       }
52     }
53   }
54 }

    row 18,用来处理drop事件,row 30的asyncdrop()方法用来打来相应对象的editor.

    现在editor area已经可以接收拖入对象了。下一步要使一个view支持拖出对象的功能。下面的例子是在pass gate view中的createpartcontrol()方法中为一个treeviewer添加拖出功能。

passgateview.java
01 private void initdraganddrop() {
02     transfer[] transfer = new transfer[] { localselectiontransfer
03         .getinstance() };
04     localselectiondragadapter adapter = new localselectiondragadapter(
05         viewer);
06     viewer.adddragsupport(dnd.drop_move | dnd.drop_copy, transfer, adapter);
07 
08     localselectiondropadapter dropadapter = new localselectiondropadapter(
09         viewer);
10     viewer.adddropsupport(dnd.drop_move | dnd.drop_copy, transfer,
11         dropadapter);
12   }
      row 06 treeviewer添加了监听拖动的事件,当在treeviewer中有拖动时,localselectiondragadapter把拖动的对象放入localselectiontransfer中,通过其传到 editor area中。
localselectiondragadapter.java
01 public class localselectiondragadapter extends dragsourceadapter {
02 
03   iselectionprovider selectionprovider;
04 
05   public localselectiondragadapter(iselectionprovider provider) {
06     selectionprovider = provider;
07   }
08 
09   public void dragfinished(dragsourceevent event) {
10     // todo auto-generated method stub
11     super.dragfinished(event);
12     system.out
13         .println("dragsourcelistener.dragfinished(dragsourceevent event)");
14   }
15 
16   public void dragsetdata(dragsourceevent event) {
17     system.out
18         .println("dragsourcelistener.dragsetdata(dragsourceevent event)");
19     dragsource dragsource = (dragsource) event.widget;
20     control control = dragsource.getcontrol();
21     if (control != control.getdisplay().getfocuscontrol()) {
22       event.doit = false;
23       return;
24     }
25 
26     istructuredselection selection = (istructuredselection) selectionprovider
27         .getselection();
28 
29     if (selection.isempty()) {
30       event.doit = false;
31       return;
32     }
33     localselectiontransfer.getinstance().setselection(selection);
34     event.doit = true;
35   }
36 
37   public void dragstart(dragsourceevent event) {
38     system.out
39         .println("dragsourcelistener.dragstart(dragsourceevent event)");
40   }
41 }

        row 33 ,将拖动的对象放入localselectiontransfer中。row 44 设置拖动有效,设为false的话,拖动无效。下面是localselectiontransfer的实现。很容易理解。


localselectiontransfer.java

001 public class localselectiontransfer extends bytearraytransfer {
002 
003   private static final string type_name = "local-selection-transfer-format" 

         + (new long(system.currenttimemillis())).tostring(); //$non-nls-1$;
004 
005   private static final int typeid = registertype(type_name);
006 
007   private static final localselectiontransfer instance = new localselectiontransfer();
008 
009   private iselection selection;
010 
011   private long selectionsettime;
012 
013   /**
014    * only the singleton instance of this class may be used.
015    */
016   private localselectiontransfer() {
017   }
018 
019   /**
020    * returns the singleton.
021    * 
022    * @return localselectiontransfer
023    */
024   public static localselectiontransfer getinstance() {
025     return instance;
026   }
027 
028   /**
029    * returns the local transfer data.
030    * 
031    * @return the local transfer data
032    */
033   public iselection getselection() {
034     return selection;
035   }
036 
037   /**
038    * tests whether native drop data matches this transfer type.
039    * 
040    * @param result
041    *            result of converting the native drop data to java
042    * @return true if the native drop data does not match this transfer type.
043    *         false otherwise.
044    */
045   private boolean isinvalidnativetype(object result) {
046     return !(result instanceof byte[])
047         || !type_name.equals(new string((byte[]) result));
048   }
049 
050   /**
051    * returns the type id used to identify this transfer.
052    * 
053    * @return the type id used to identify this transfer.
054    */
055   protected int[] gettypeids() {
056     return new int[] { typeid };
057   }
058 
059   /**
060    * returns the type name used to identify this transfer.
061    * 
062    * @return the type name used to identify this transfer.
063    */
064   protected string[] gettypenames() {
065     return new string[] { type_name };
066   }
067 
068   /**
069    * overrides org.eclipse.swt.dnd.bytearraytransfer#javatonative(object,
070    * transferdata). only encode the transfer type name since the selection is
071    * read and written in the same process.
072    * 
073    * @see org.eclipse.swt.dnd.bytearraytransfer#javatonative(java.lang.object,
074    *      org.eclipse.swt.dnd.transferdata)
075    */
076   public void javatonative(object object, transferdata transferdata) {
077     byte[] check = type_name.getbytes();
078     super.javatonative(check, transferdata);
079   }
080 
081   /**
082    * overrides
083    * org.eclipse.swt.dnd.bytearraytransfer#nativetojava(transferdata). test if
084    * the native drop data matches this transfer type.
085    * 
086    * @see org.eclipse.swt.dnd.bytearraytransfer#nativetojava(transferdata)
087    */
088   public object nativetojava(transferdata transferdata) {
089     object result = super.nativetojava(transferdata);
090     if (isinvalidnativetype(result)) {
091       pwdgateplugin.log("invalid nattive type", new exception(
092           "invalid nattive type"));
093     }
094     return selection;
095   }
096 
097   /**
098    * sets the transfer data for local use.
099    * 
100    * @param s
101    *            the transfer data
102    */
103   public void setselection(iselection s) {
104     selection = s;
105   }
106 
107   /**
108    * returns the time when the selection operation this transfer is associated
109    * with was started.
110    * 
111    * @return the time when the selection operation has started
112    * 
113    * @see org.eclipse.swt.events.typedevent#time
114    */
115   public long getselectionsettime() {
116     return selectionsettime;
117   }
118 
119   /**
120    * sets the time when the selection operation this transfer is associated
121    * with was started. if assigning this from an swt event, be sure to use
122    * <code>setselectiontime(event.time & 0xffff)</code>
123    * 
124    * @param time
125    *            the time when the selection operation was started
126    * 
127    * @see org.eclipse.swt.events.typedevent#time
128    */
129   public void setselectionsettime(long time) {
130     selectionsettime = time;
131   }
132 }

          其实不光是拖到area editor,以上例子稍加改造,也可以实现拖到别的控件中,任何control都可以添加托拽功能,例如可以从一个表格拖到另一个表格中,或拖到一个面板中。托拽功能让软件的可用性又提高了一个档次。

扫描关注微信公众号