我是Eclipse RCP/Plug-ins和SWT的新手。我想通过拖放来重新排列表格项目。通过拖放对表格行重新排序?
我有一个TableViewer
其中包含一个表与我的自定义元素类型ITask
(我的自定义元素包装在TableItem
)。我发现的所有教程都是关于树或在不同表格之间拖动的,这不是我所需要的。
所以我想知道如何通过拖放重新排序表行。
我是Eclipse RCP/Plug-ins和SWT的新手。我想通过拖放来重新排列表格项目。通过拖放对表格行重新排序?
我有一个TableViewer
其中包含一个表与我的自定义元素类型ITask
(我的自定义元素包装在TableItem
)。我发现的所有教程都是关于树或在不同表格之间拖动的,这不是我所需要的。
所以我想知道如何通过拖放重新排序表行。
这有点长,但是你可以在代码中做一些改变。我没有列入进口; Eclipse可以自动为你做。
我使用了Spring的BeanUtils类,但是您可以使用任何可以深度拷贝POJO的lib(或者自己写)。我假设你的ITask有一个setOrder(int)方法并且是可序列化的(并且它符合POJO)
您需要为ITask创建Transfer-type:SimpleObjectTransfer是来自Eclipse GEF的IBM代码。你可以Google/GrepCode它。
public final class TaskTransfer extends SimpleObjectTransfer {
public static final TaskTransfer INSTANCE = new TaskTransfer();
private TaskTransfer() {
}
@Override
protected String getTypeNamePrefix() {
return "TASK_TRANSFER_FORMAT";
}
}
一个ViewerDropAdapter:
public class MyDropAdapter<TM extends ITask> extends ViewerDropAdapter {
private final Class<TM> targetModelClass;
private List<TM> listOfModels;
protected MyDropAdapter(Viewer viewer, Class<TM> targetModelClass, List<TM> listOfModels) {
super(viewer);
this.listOfModels = listOfModels;
this.targetModelClass = targetModelClass;
}
@Override
public boolean performDrop(Object arg0) {
boolean ret = false;
TM targetModel = targetModelClass.cast(determineTarget(getCurrentEvent()));
if (targetModel != null) {
if (List.class.isAssignableFrom(arg0.getClass())) {
ret = processDropToTable(targetModel, arg0);
getViewer().refresh();
}
}
return ret;
}
public final boolean processDropToTable(TM targetModel, Object data) {
List<TM> transferredModels = (List<TM>) data;
List<TM> copyOfTransferredModels = transferredModels;
switch (getCurrentOperation()) {
case DND.DROP_COPY:
copyOfTransferredModels = deepCopyBeanList(transferredModels, new String[]{});
break;
case DND.DROP_MOVE:
// moving
break;
default:
throw new UnsupportedOperationException(getCurrentOperation() + " is not supported!");
}
adjustPosition(transferredModels, copyOfTransferredModels, targetModel);
return true;
}
private void adjustPosition(List<TM> transferredModels, List<TM> copyOfTransferredModels, TM targetModel) {
int transferredObjectPosition = listOfModels.indexOf(transferredModels.get(0));
listOfModels.removeAll(copyOfTransferredModels);
addModelsToNewLocation(copyOfTransferredModels, targetModel, listOfModels, transferredObjectPosition);
for (int i = 0; i < listOfModels.size(); i++) {
int orderPosition = i * 10 + 10;
listOfModels.get(i).setOrder(orderPosition);
}
}
protected void addModelsToNewLocation(List<TM> transferredModels, TM targetModel, List<TM> targetList, int transferredObjectPosition) {
switch (determineLocation(getCurrentEvent())) {
case LOCATION_AFTER:
case LOCATION_ON:
int i;
if (!transferredModels.contains(targetModel)) {
i = targetList.indexOf(targetModel) + 1;
} else {
i = transferredObjectPosition;
}
targetList.addAll(i, transferredModels);
break;
case LOCATION_BEFORE:
if (!transferredModels.contains(targetModel)) {
i = targetList.indexOf(targetModel);
} else {
i = transferredObjectPosition;
}
targetList.addAll(i, transferredModels);
break;
case LOCATION_NONE:
default:
break;
}
}
private List<TM> deepCopyBeanList(List<TM> transferredModels, String[] ignoreProperties) {
List<TM> targetList = new LinkedList<TM>();
for (TM element : transferredModels) {
try {
@SuppressWarnings("unchecked")
TM copy = (TM) element.getClass().newInstance();
BeanUtils.copyProperties(element, copy, ignoreProperties);
targetList.add(copy);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return targetList;
}
@Override
public boolean validateDrop(Object arg0, int arg1, TransferData arg2) {
boolean ret = false;
for (Transfer t : new Transfer[]{TaskTransfer.INSTANCE}) {
if (t.isSupportedType(arg2)) {
ret = true;
break;
}
}
return ret;
}
}
一个的DragSourceListener
public class MyDragSourceListener implements DragSourceListener {
private final Viewer dragSourceViewer;
private final boolean multiObjectsEnabled;
private final Class<?> transferrableElementClass;
private Object[] draggedObjects;
public MyDragSourceListener(Viewer dragSourceViewer, boolean multiObjectsEnabled, Class<?> transferrableElementClass) {
this.dragSourceViewer = dragSourceViewer;
this.multiObjectsEnabled = multiObjectsEnabled;
this.transferrableElementClass = transferrableElementClass;
}
@Override
public void dragStart(DragSourceEvent event) {
Control source = ((DragSource) event.getSource()).getControl();
draggedObjects = null;
if (dragSourceViewer.getControl().equals(source)) {
if (multiObjectsEnabled) {
draggedObjects = ((StructuredSelection) dragSourceViewer.getSelection()).toArray();
} else {
draggedObjects = new Object[]{((StructuredSelection) dragSourceViewer.getSelection()).getFirstElement()};
}
}
event.doit = draggedObjects.length > 0 && transferredDataIsSupported();
}
private boolean transferredDataIsSupported() {
boolean ret = true;
for (Object o : draggedObjects) {
if (o == null || !transferrableElementClass.isAssignableFrom(o.getClass())) {
ret = false;
break;
}
}
return ret;
}
@Override
public void dragSetData(DragSourceEvent event) {
event.data = Arrays.asList(draggedObjects);
}
@Override
public void dragFinished(DragSourceEvent event) {
if (event.detail != DND.DROP_NONE) {
dragSourceViewer.refresh();
}
draggedObjects = null;
}
}
和地点代码有点像这样在你的视野:
List<ITask> tasks = new WritableList(new ArrayList<ITask>(), ITask.class);
// Let's say tableViewerTasks is your TableViewer's name
DragSource sourceTasks = new DragSource(tblTasks, DND.DROP_MOVE);
sourceTasks.setTransfer(new Transfer[]{TaskTransfer.INSTANCE});
sourceTasks.addDragListener(new MyDragSourceListener(tableViewerTasks, true, ITask.class));
DropTarget targetTasks = new DropTarget(tblTasks, DND.DROP_MOVE);
targetTasks.setTransfer(new Transfer[]{TaskTransfer.INSTANCE});
targetTasks.addDropListener(new MyDropAdapter<ITask>(tableViewerTasks, ITask.class, tasks));
谢谢你的回答。我可以使用'LocalSelectionTransfer'而不是创建自己的传输类型吗? – Nicholas
HTTP://www.java2s .com/Tutorial/Java/0280__SWT/DragandDropinsideTable.htm – SomeDude
你的TableItem是简单文本还是POJO?如果ITask是由POJO-s实现的,那么这个链接的例子对你来说是不够的。 –
@AdamHorvath我的ITask元素不仅仅是简单的文本元素。它们具有表格中显示的字符串名称字段,因此用户可以看到它们,但实际上它们包含算法和其他重要字段。 – Nicholas