SWT/JFace 組件添加拖拽功能

一個簡單的實現圖片之間拖拽重排的例子

package com.devin.swt.widgets.dnd.demo;

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

import com.devin.swt.widgets.dnd.imageEffects.DropShadow;

public class PhotoShuffler {

	private static Display display;

	public static void main(String[] args) {

		// setup the SWT window
		display = new Display();
		final Shell shell = new Shell(display);
		shell.setLayout(new FillLayout());
		shell.setText("Photo Shuffler");

		// initialize a parent composite with a grid layout manager
		Composite parent = new Composite(shell, SWT.NONE);
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 2;
		gridLayout.marginWidth = 20;
		parent.setLayout(gridLayout);

		// determine the path where the pictures are stored
		String path = System.getProperty("user.dir") + "/images/";
		File imageDir = new File(path);

		// initialize an array with the photograph names
		// loop over the photo array and establish all listeners
		List<File> files = Arrays.stream(imageDir.listFiles()).filter(f -> f.isFile() && f.getName().endsWith(".png"))
				.collect(Collectors.toList());
		for (File file : files) {
			// labels serve as containers for the images
			Label label = new Label(parent, SWT.NONE);
			Image img = new Image(display, file.getAbsolutePath());
			label.setImage(img);

			// enable each label to be draggable
			DragSource source = new DragSource(label, DND.DROP_NONE);
			source.setTransfer(TextTransfer.getInstance());

			// add a drag listener
			source.addDragListener(new MyDragSourceListener(parent, source));

			// enable each label to be a drop target
			DropTarget target = new DropTarget(label, DND.DROP_NONE);
			target.setTransfer(new Transfer[] { TextTransfer.getInstance() });
			target.addDropListener(new MyDropTargetListener(parent, target));
		}

		// show the SWT window
		shell.pack();
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}

		// tear down the SWT window
		display.dispose();
	}

	private static class MyDragSourceListener extends DragSourceAdapter {
		private Composite parentComposite;
		private DragSource source;

		/**
		 * @param parentComposite - the composite that holds all pictures
		 * @param source          - the drag source
		 *
		 */
		public MyDragSourceListener(Composite parentComposite, DragSource source) {
			this.parentComposite = parentComposite;
			this.source = source;
		}

		@Override
		public void dragStart(DragSourceEvent dragSourceEvent) {
			 // getting control widget - Label in this case
	        Label label = ((Label) ((DragSource) dragSourceEvent.getSource()).getControl());
	        // make the drag icon the dragged image itself
	        dragSourceEvent.image = label.getImage();

	        // add shadow to drag icon
	        dragSourceEvent.image = new Image(display,
	                DropShadow.dropShadow(dragSourceEvent.image.getImageData(),
	                        display.getSystemColor(SWT.COLOR_BLACK),
	                        10, 30, 100));
		}

		/**
		 * The method computes the position / index of the source control (label) in the
		 * children array of the parent composite. This index is passed to the drop
		 * target using the data field of the drag source event.
		 */
		@Override
		public void dragSetData(DragSourceEvent event) {
			for (int i = 0; i < parentComposite.getChildren().length; i++) {
				if (parentComposite.getChildren()[i].equals(source.getControl())) {
					event.data = new Integer(i).toString();
					break;
				}
			}
		}

	}
	
	private static class MyDropTargetListener extends DropTargetAdapter {
	    private Composite parentComposite;
	    private DropTarget target;

	    /**
	     * @param parentComposite - the composite that holds all pictures
	     * @param target - the drop target
	     */
	    public MyDropTargetListener(Composite parentComposite, DropTarget target) {
	        this.parentComposite = parentComposite;
	        this.target = target;
	    }

	    /**
	     * This method moves the dragged picture to the new position and shifts the
	     * old picture to the right or left.
	     */
		@Override
		public void drop(DropTargetEvent event) {
			// retrieve the stored index
	        int sourceIndex = Integer.valueOf(event.data.toString());

	        // compute the index of target control
	        Control targetControl = target.getControl();
	        int targetIndex = -1;
	        for (int i = 0; i < parentComposite.getChildren().length; i++) {
	            if (parentComposite.getChildren()[i].equals(targetControl)) {
	                targetIndex = i;
	                break;
	            }
	        }

	        Control sourceControl = parentComposite.getChildren()[sourceIndex];
	        // do not do anything if the dragged photo is dropped at the same
	        // position
	        if (targetIndex == sourceIndex)
	            return;

	        // if dragged from left to right
	        // shift the old picture to the left
	        if (targetIndex > sourceIndex) {
	            sourceControl.moveBelow(targetControl);
	        }
	        // if dragged from right to left
	        // shift the old picture to the right
	        else {
	            sourceControl.moveAbove(targetControl);
	        }

	        // repaint the parent composite
	        parentComposite.requestLayout();
		}
	    
	}
	
}

上面中爲拖拽添加陰影效果的算法參考自Eclipse 教程中的 Simple Image Effects for SWT
,需要導入額外的JAR 包:

效果圖如下:
在這裏插入圖片描述

詳細的教程和資料參考如下站點:

Drag and Drop
Drag and Drop in the Eclipse UI
Implementation drag and drop in Eclipse plug-ins and applications - Tutorial
Drag Drop « SWT JFace Eclipse>>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章