我正在嘗試在我們的產品中加入拖放功能。我創建了一個新的自定義視圖,該視圖具有樹結構,並且有興趣將此樹中的內容放到應用程序本身內已有的樹結構中。無法實現拖放操作; dragSetData沒有被調用
我已經使用了產品所期望的相同的自定義傳輸類型。但是,在調試過程中,我發現DragSourceEvent
的數據或數據類型都沒有設置。 兩者都是null
的值。此外我的dragSetData
也沒有被調用。
請求你給我提供一些建議....
我正在嘗試在我們的產品中加入拖放功能。我創建了一個新的自定義視圖,該視圖具有樹結構,並且有興趣將此樹中的內容放到應用程序本身內已有的樹結構中。無法實現拖放操作; dragSetData沒有被調用
我已經使用了產品所期望的相同的自定義傳輸類型。但是,在調試過程中,我發現DragSourceEvent
的數據或數據類型都沒有設置。 兩者都是null
的值。此外我的dragSetData
也沒有被調用。
請求你給我提供一些建議....
事件的數據的下降得到數據後,才設置。這應該會自動發生,但它起初也不適用於我。
經過一番研究,我想出了一個解決方法,雖然我不確定這是否是框架打算的。我伸出我的解決方案的org.eclipse.jface.viewers.ViewerDropAdapter,但它也應該延伸org.eclipse.swt.dnd.DropTargetAdapter工作:
public class MyViewerDropAdapter extends ViewerDropAdapter {
// implement the abstract methods
// the next two methods are the important part:
// override the non-abstract methods dragEnter and dragOperationChanged
// if your user just moves the mouse without pressing a key, event.detail
// equals DND.DROP_DEFAULT. In this case you have to change detail to
// your default operation (in this case DROP_COPY)
@Override
public void dragEnter(DropTargetEvent event) {
if (event.detail == DND.DROP_DEFAULT) {
if ((event.operations & DND.DROP_COPY) != 0) {
event.detail = DND.DROP_COPY;
} else {
event.detail = DND.DROP_NONE;
}
}
super.dragEnter(event);
}
// the same for this method. It will be called, when the user
// presses the CTRL or SHIFT button (on windows) while dragging.
// We need it here to set the DROP_DEFAULT back to DROP_COPY.
// Otherwise your default will go back to DROP_NONE after the user
// released the key.
@Override
public void dragOperationChanged(DropTargetEvent event) {
if (event.detail == DND.DROP_DEFAULT) {
if ((event.operations & DND.DROP_COPY) != 0) {
event.detail = DND.DROP_COPY;
} else {
event.detail = DND.DROP_NONE;
}
}
}
}
當你再放入滴你的樹查看器的支持,一定要設置除其他人(在API文檔沒有提及據我所知)的DND.DROP_DEFAULT操作:
myTreeViewer.addDropSupport(DND.DROP_COPY | DND.DROP_DEFAULT,
new Transfer[] { myByteTransfer.getInstance() },
new MyViewerDropAdapter(myTreeViewer));
我這樣做後,dragSetData接到電話和一切工作按預期。
控制檯輸出顯示你對一些事件的順序:
Start Drag
dragEnter called
dragSetData called
drop called
performDrop called
Finshed Drag
解決方案
如果我們想爲用戶拖動項不使用Meta鍵我們應該總是允許系統默認在拖放結束時拖動操作。在Windows上,這恰好是DND.DRAG_MOVE
操作(我相信其他平臺的情況也是如此)。
source.addDragSupport(DND.DROP_MOVE, new Transfer[] { DragSelectionListener.getTransfer() }, new DragSelectionListener(viewer));
target.addDropSupport(DND.DROP_MOVE, new Transfer[]{ DropListListener.getTransfer() }, new DropListListener(viewer));
說明
三組操作的應相交:
只有然後放下目標將驗證接收到的下降和拖動源將被請求的數據。
調查
元鍵的處理在org.eclipse.swt.dnd.DropTarget.setEventData()
做行
operations[0] = osToOp(operations[0]) & style;
if (operations[0] == DND.DROP_NONE) return false;
相交從與來自系統拖放操作價值DropTarget的風格是基於DragSource上,但剝離的DND.DRAG_DEFAULT
。如果這兩個不相交,則操作被中止。
進一步下來這個集合與從元鍵被按下計算出來的集合進行比較。操作可能會再次中止。
if ((operation & operations[0]) == 0) operation = DND.DROP_NONE;
此行爲可以被控制傳遞到DND.DROP_DEFAULT
addDropSupport()
,但隨着用戶選擇的操作將被然後與DND.DROP_MOVE
即更差,這將被過濾掉早期如果沒有用作的addDropSupport()
參數。我認爲DND.DROP_DEFAULT
處理是打破,不應該依靠。這是有用的,如果有效地防止了第一個條件。