最近在項目中,需要完成從資料總管(navigator)向GEF編輯器中拖放結點的功能。
現總結個人體會如下(具體的實作流程,請參考http://www.eclipse.org/articles/Article-GEF-dnd/GEF-dnd.html):
1. GEF封裝了底層的SWT拖放。無需自己定義DragSource和DropTarget。
2. GEF的拖拽功能需要
(1).一個可以注冊在GEF 中上的監聽器,該監聽器需實作TransferDropTargetListener接口,一般來講,直接繼承AbstractTransferDropTargetListener類會更好些。
public class FileTransferDropTargetListener
extends AbstractTransferDropTargetListener {
//初始化指令所需要的工廠,第二步建立
private FileLabelFactory factory = new FileLabelFactory();
public FileTransferDropTargetListener(EditPartViewer viewer, Transfer xfer) {
super(viewer, xfer);
}
//紅色字型應特别注意,這是拖放是否被接受的關鍵,他是拖放資料的注冊類型。
//應根據需求選擇自己的類型,預設為處理文本拖放的TextTransfer
public FileTransferDropTargetListener(EditPartViewer viewer) {
super(viewer,FileTransfer.getInstance());
}
/*
*傳回GEF中建立模型所需要的request,對request的設定采用工廠模式
*/
protected Request createTargetRequest() {
CreateRequest request = new CreateRequest();
request.setFactory(factory);
return request;
}
protected void updateTargetRequest() {}
}
(2).一個生成拖放資料的工廠類,該類需實作CreationFactory 接口。
public class FileLabelFactory implements CreationFactory {
private String text = "";
/*該方法傳回拖拽所産生的資料,應根據項目需求進行更改。一個可行的改良建
*議是在該工程類中建立template字段,并在構造函數中初始化,該方法根據
*template傳回新的類型
*/
public Object getNewObject() {
LogicLabel label = new LogicLabel();
label.setLabelContents(text);
return label;
}
/*該方法傳回拖拽所産生資料的類型
*GEF中,将該資料的類型,設定到request中。進而幫助在對應的Editpart中完成*操作
*/
public Object getObjectType() {
return LogicLabel.class;
}
public void setText(String s) {
text = s;
}
}
(3).在GEF編輯器中,為GraphicalViewer注冊該監聽器,一般在initializeGraphicalViewer()方法中添加
getGraphicalViewer().addDropTargetListener( new FileTransferDropTargetListener(getGraphicalViewer()));
3. DND拖放參數
一般在監聽器中的處理拖動方法中,對拖動的操作類型進行設定。如:
protected void handleDragOver() {
getCurrentEvent().detail = DND.DROP_COPY;
super.handleDragOver();
}
| |
| |
| |
| |
4. Transfer
Transfer是拖放的關鍵。不同類型的拖放資料,應在監聽器的初始化時,選擇合适的。
其中,TextTransfer預設處理文本拖動,FileTransfer預設處理檔案拖動,在我的項目中,我采用的是LocalSelectionTransfer。