SWT中的拖放功能如何?
最近在项目开发中需要对树(Tree)的层次结构进行调整,由于SWT是基于操作系统的事件模型的一种开发控件,所以想到利用鼠标的拖放功能对树的节点进行移动,即直观也提高了客户体验。
SWT的拖放功能的实现主要使用了DragSource、DropTarget这两个类,开发人员只需要实现其事件的接口,既可以对控件上的文本、HTML、RTF及附件进行拖放操作,即把一个控件上的文本、HTML、RTF及附件拖放到另一个控件。
Tree是由TreeItem控件组成,所以移动树节点就相当于移动TreeItem,这里并非真的移动控件,而是把源控件的信息(文本、HTML、RTF及附件)通过事件传递到目标控件,目标控件也是新创建的,如果不是复制而只是移动,则要把源控件销毁掉。
例子实现思路及源代码:本例子为左边是目标树,右边是用TabFolder实现了几棵源树,同时目标树本身也是源树,即实现多个源对单个目标进行操作。实现过程把几个源树放到了一个Tree[ ]集合里,用于分清源树到底是哪一棵,才能得到在源树上的选择的节点。本例的主要功能是:实现把其他源树的节点移动到某一个目标树上,同时实现目标树上的节点自由替换位置。
代码:

publicclassSetSubSWTextendsDialog...{

protectedTreesubtree;

protectedTreepreTree;//单位

protectedTreeroomTree;//科室

protectedTableunitTable;//科室

protectedDisplaydisplay;

protectedShellshell;

protectedTreetree;

protectedListnewList=newArrayList();

protectedListmodifyList=newArrayList();

protectedListdeleteList=newArrayList();

protectedMapmap=newHashMap();

protectedMapmapSave=newHashMap();

protectedObjectresult;

protectedSashFormmainSashForm;

protectedTextTransfertextTransfer;

protectedFileTransferfileTransfer;

protectedTree[]eachTrees;

//protectedTreeItem[]dragSourceItem;

protectedintindex;

protectedMapdataMap;//缓存

protectedListtypeList;//缓存

protectedMaprelMap;//缓存


/***//**
*Createthedialog
*
*@paramparent
*@paramstyle
*/
publicSetSubSWT(Shellparent,Treesubtree,MapdataMap,ListtypeList,

MaprelMap,intstyle)...{
super(parent,style);
this.subtree=subtree;
this.dataMap=dataMap;
this.typeList=typeList;
this.relMap=relMap;
}

///**
//*Createthedialog
//*@paramparent
//*/
//publicSetSubSWT(Shellparent){
//this(parent,SWT.NONE);
//}

///**
//*Launchtheapplication
//*
//*@paramargs
//*/
//publicstaticvoidmain(String[]args){
//try{
//System.out.println("args[0]=="+args[0]);
//SWTDataViewUtil.httpUrl=args[0]+"/subactionswt.do?action=";
//SetSubSWTwindow=newSetSubSWT();
//window.open();
//}catch(Exceptione){
//e.printStackTrace();
//}
//}


/***//**
*Openthewindow
*/

publicObjectopen()...{
display=getParent().getDisplay();

createContents();
shell.open();
shell.layout();

while(!shell.isDisposed())...{
if(!display.readAndDispatch())
display.sleep();
}
returnresult;
}


/***//**
*Createcontentsofthewindow
*/

protectedvoidcreateContents()...{
shell=newShell();
shell.setLayout(newFillLayout());
shell.setText("会计科目设置");


/**//*
*Transfer是一个可以提供数据在Javarepresentation与platformspecific
*representation之间交互的抽象类.下面是几个format:TextTransferString"hello
*world"RTFTransferString"{/rtf1/b/ihelloworld}"FileTransfer
*String[]newString[]{file1.getAbsolutePath(),
*file2.getAbsolutePath()}
*
*TransferData包含了很多特定于平台的公用的属性,应用不应该直接去访问这些属性。
*如果真的有必要去访问这些属性,那么我们可以通过扩展Transfer类来完成对特定平台的额外操作。
*/
textTransfer=TextTransfer.getInstance();
fileTransfer=FileTransfer.getInstance();

//finalColorred=display.getSystemColor(SWT.COLOR_GREEN);
//finalColoryellow=display.getSystemColor(SWT.COLOR_GRAY);
//tree.addListener(SWT.EraseItem,newListener(){
//publicvoidhandleEvent(Eventevent){
//if((event.detail&SWT.SELECTED)==0)
//return;/*itemnotselected*/
//intclientWidth=tree.getClientArea().width;
//GCgc=event.gc;
//ColoroldForeground=gc.getForeground();
//ColoroldBackground=gc.getBackground();
//gc.setForeground(red);
//gc.setBackground(yellow);
//gc.fillGradientRectangle(0,event.y,clientWidth,event.height,
//false);
//gc.setForeground(oldForeground);
//gc.setBackground(oldBackground);
//event.detail&=~SWT.SELECTED;
//}
//});

shell.setMaximized(true);
//Canvascanvas=newCanvas(shell,SWT.BORDER);
//canvas.setLayout(newFillLayout());

mainSashForm=newSashForm(shell,SWT.HORIZONTAL);
mainSashForm.setBackground(shell.getDisplay().getSystemColor(
SWT.COLOR_TITLE_BACKGROUND));
finalGroupleftGroup=newGroup(mainSashForm,SWT.NONE|SWT.CENTER);
leftGroup.setText("会计科目");
leftGroup.setLayout(newFillLayout());
finalTabFoldersubtabFolder=newTabFolder(leftGroup,SWT.NONE);

finalTabItemsubtabItem=newTabItem(subtabFolder,SWT.NONE);
subtabItem.setText("会计科目");
tree=newTree(subtabFolder,SWT.FULL_SELECTION);
tree.setLinesVisible(true);
addExistItems();

tree.addListener(SWT.Selection,newListener()...{


publicvoidhandleEvent(Eventevent)...{
System.out
.println(tree.getSelection()[0].getData("SetSubData"));
}

});
subtabItem.setControl(tree);


Transfer[]types=newTransfer[]...{TextTransfer.getInstance()};
intoperations=DND.DROP_MOVE|DND.DROP_COPY|DND.DROP_LINK;

finalDragSourcetreeSource=newDragSource(tree,operations);
treeSource.setTransfer(types);

treeSource.addDragListener(newDragSourceListener()...{

publicvoiddragStart(DragSourceEventevent)...{
TreeItem[]selection=((Tree)((DragSource)event.widget)
.getControl()).getSelection();
//只能移动选中并且为最子结点。
//if(selection.length>0
//&&selection[0].getItemCount()==0){//选中并且为最子结点。

if(selection.length>0)...{
event.doit=true;
//intselectedCount=((Tree)((DragSource)
//event.widget)
//.getControl()).getSelection().length;
//dragSourceItem=newTreeItem[selectedCount];
//for(inti=0;i<selectedCount;i++){
//dragSourceItem[i]=selection[i];
//}

}else...{
event.doit=false;
}
};


publicvoiddragSetData(DragSourceEventevent)...{
event.data=String.valueOf(typeList.size());//最后一个是保存左边树,用于移动节点位置用。;