天天看點

元件的拖拽功能(Drag and Drop)

作業系統中最常用的拖拽功能就是檔案的移動複制,拖 拽功能提高了軟體的簡用性。SWT也支援拖拽功能,不過程式設計實作比較繁瑣。圖18.1是實作拖拽的示意圖,它首先要設定好拖拽源(DragSource) 和能夠接收的目标地(DropTarget),然後再設定一個運送拖拽資料的載體(Transfer),最後最繁瑣的就是要給DragSource和 DropTarget分别添加拖拽監聽器,并根據拖拽途中的各種情況實作監聽器的各方法。

元件的拖拽功能(Drag and Drop)
元件的拖拽功能(Drag and Drop)

圖18.1 SWT拖拽實作的示意圖 圖18.2 拖拽執行個體一

下面給出一個拖拽執行個體,其運作效果如圖18.2所示。圖的左邊是一個按鈕,右邊是一個文本框,可以将按鈕文字拖拽到文本框中。如果按住Shift鍵拖拽,則為移動文字,結果是按鈕變成空白,文字移到文本框。具體實作代碼如下:

public class DragAndDrop1 {

private TextTransfer textTransfer = TextTransfer.getInstance ();

private Button sourceText;

private Text targetText;

public static void main(String[] args) {

new DragAndDrop1().open();

}

private void open() {

final Display display = Display.getDefault ();

final Shell shell = new Shell();

shell.setSize(300, 100);

// ---------建立視窗中的其他界面元件-------------

// 建立視窗元件

shell.setLayout(new FillLayout());

sourceText = new Button(shell, SWT.NONE );

sourceText.setText("HelloWolrd");

new Label(shell, SWT.NONE );// 分隔區

targetText = new Text(shell, SWT.BORDER );

// --------- 拖動設定-----------------

// 設定sourceText為拖拽源。允許資料被移動或複制

DragSource source = new DragSource(sourceText, DND.DROP_MOVE | DND.DROP_COPY );

source.setTransfer(new Transfer[] { textTransfer });// 設定傳輸載體為文本型

source.addDragListener(new MyDragSourceListener());

// 設定targetText為目标地

DropTarget target = new DropTarget(targetText, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT );

target.setTransfer(new Transfer[] { textTransfer });

target.addDropListener(new MyDropTargetListener());

// -----------------END------------------------

shell.layout();

shell.open();

while (!shell.isDisposed()) {

if (!display.readAndDispatch())

display.sleep();

}

display.dispose();

}

private class MyDragSourceListener implements DragSourceListener {

// 判斷是否允許拖拽。這裡設定空字串時不允許拖拽

public void dragStart(DragSourceEvent event) {

Button button = getSource(event);// getSource是自定義方法

if (button.getText().trim().equals(""))

event.doit = false;

}

// 自定義方法,取得拖拽源元件

private Button getSource(DragSourceEvent event) {

DragSource source = (DragSource) event.widget;

Button button = (Button) source.getControl();// 即sourceButton

return button;

}

// 設定需要用Transfer傳輸的資料

public void dragSetData(DragSourceEvent event) {

if (textTransfer.isSupportedType(event.dataType)) {// 是否支援拖拽的資料類型

Button button = getSource(event);

event.data = button.getText();

}

}

// 拖拽操作完成後執行此方法

public void dragFinished(DragSourceEvent event) {

if (event.detail == DND.DROP_MOVE ) {// 如果是移動則删除sourceText中的文字

Button button = getSource(event);

button.setText("");

}

}

}

private class MyDropTargetListener implements DropTargetListener {

// 滑鼠進入目标元件時調用此方法

public void dragEnter(DropTargetEvent event) {

// 預設為DND.DROP_DEFAULT,這裡将其設為複制;按住Ctrl鍵為DND.DROP_COPY;按住Shift鍵為DND.DROP_MOVE。

if (event.detail == DND.DROP_DEFAULT )

event.detail = DND.DROP_COPY ;

}

// 滑鼠在目标元件範圍時會不斷調用此方法。在此方法中主要是設定event.feedback,其可能值有:

//FEEDBACK_EXPAND 使目前光标下的項展開,以便拖拽到子項上,僅用于樹型元件。

//FEEDBACK_INSERT_AFTER 在某項處于光标下之後顯示一個插入标記,僅用于表格和樹。

//FEEDBACK_INSERT_BEFORE 在某項處于目前光标下之前顯示一個插入标記,僅用于表格和樹。

//FEEDBACK_NONE 什麼也不做.

//FEEDBACK_SCROLL 使目标元件可以滾動,以便可以拖到目前看不見的項上,僅用于表格和樹。

//FEEDBACK_SELECT 使目前光标下的項被選中,僅用于表格和樹。

public void dragOver(DropTargetEvent event) {

event.feedback = DND.FEEDBACK_NONE ;

}

// 當按下或放開輔助按鍵(如Ctrl, Shift)時調用此方法

public void dragOperationChanged(DropTargetEvent event) {

if (event.detail == DND.DROP_DEFAULT )

event.detail = DND.DROP_COPY ;

}

// 當滑鼠離開目标元件時會調用此方法

public void dragLeave(DropTargetEvent event) {}

// 在完成拖拽操作,執行drop方法之前調用此方法。

public void dropAccept(DropTargetEvent event) {}

// 在完成拖拽操作時最後調用的方法

public void drop(DropTargetEvent event) {

if (textTransfer.isSupportedType(event.currentDataType)) {

String str = (String) event .data;// 取出傳輸資料

DropTarget target = (DropTarget) event.widget;

Text text = (Text) target.getControl();// 即targetText

text.setText(str);

}

}

}

}

程式說明:

● 雖然拖拽常用于表格和樹,而本節是用按鈕和文本框做執行個體,但基本原理和代碼結構都一樣。

● 可以設定多個拖拽目标地。一個元件既可以是拖拽源,也可以是拖拽目标地。

● event.detail= DND.DROP_NONE可以使拖拽失效。

● TextTransfer是Transfer的子類,檢視Transfer的類層次結構可以找到更多的拖拽傳輸載體。