在 Eclipse SWT/JFace 開發中,拖放功能是建立直觀使用者介面的關鍵技術。本文透過一個「單字拼圖遊戲」完整範例,詳細展示如何使用 DragSource、DropTarget 及 TextTransfer 實作拖放邏輯,包含資料傳輸、視覺回饋與遊戲判斷機制。
範例程式 WordJumbles 建立兩排標籤:上排為打亂順序的字母,下排為空白目標區。使用者需將字母拖曳至正確位置拼成 "ECLIPSE"。關鍵元件包括:
DND.DROP_MOVE 操作// 設定拖曳來源
int operations = DND.DROP_MOVE;
DragSource dragSource = new DragSource(label, operations);
dragSource.setTransfer(new Transfer[] { TextTransfer.getInstance() });
dragSource.addDragListener(new DragSourceListener() {
public void dragStart(DragSourceEvent event) {
if (label.getText().length() == 0) event.doit = false;
}
public void dragSetData(DragSourceEvent event) {
if (TextTransfer.getInstance().isSupportedType(event.dataType))
event.data = label.getText();
}
public void dragFinished(DragSourceEvent event) {
if (event.doit || event.detail == DND.DROP_MOVE)
label.setText(""); // 移動後清空來源
}
});
// 設定放置目標
DropTarget dropTarget = new DropTarget(label, operations);
dropTarget.setTransfer(new Transfer[] { TextTransfer.getInstance() });
dropTarget.addDropListener(new DropTargetListener() {
public void dragEnter(DropTargetEvent event) {
if (label.getText().length() != 0) event.detail = DND.DROP_NONE; // 已有內容則拒絕
}
public void drop(DropTargetEvent event) {
if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) {
label.setText((String) event.data);
check(); // 檢查是否完成拼字
}
}
});
check() 方法比對下排標籤文字與目標單字 "ECLIPSE",全符合時彈出成功訊息。建構子中使用固定亂數陣列 {5,2,6,3,1,4,0} 打亂字母順序,並為每個標籤同時註冊拖曳來源與放置目標,實現雙向拖放。
DisposeListener 釋放 DragSource/DropTarget,避免記憶體洩漏dragEnter 中檢查目標是否為空,防止覆蓋既有資料DND.DROP_MOVE 明確表達移動語意,dragFinished 清空來源標籤readAndDispatch() / sleep() 維持 UI 回應此範例展示 SWT/JFace 拖放 API 的核心用法,可作為檔案管理器、圖形編輯器等需要拖放互動應用的開發基礎。