一个简单的实现图片之间拖拽重排的例子
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>>