通过拖放重新排序表行?

时间:2016-05-17 11:59:45

标签: java eclipse-plugin drag-and-drop swt eclipse-rcp

我是Eclipse RCP / Plug-ins和SWT的新手。我想通过拖放重新排序表项。

我有一个TableViewer,其中包含一个表格,其中包含ITask类型的自定义元素(我的自定义元素包含在TableItem中)。我发现的所有教程都是关于树或在不同的表之间拖动,这不是我需要的。

所以我想知道如何通过拖放重新排序表行。

1 个答案:

答案 0 :(得分:0)

这有点长,但您可以通过一些更改在代码中完成此工作。我没有包括进口; Eclipse可以自动为您完成。

我使用了Spring的BeanUtils类,但你可以使用任何可以深度搜索POJO的lib(或编写自己的)。我假设你的ITask有一个setOrder(int)方法,并且是Serializable(它有资格获得POJO)

您需要为ITask创建一个Transfer类型:SimpleObjectTransfer是来自Eclipse GEF的IBM代码。你可以谷歌/ GrepCode它。

3

ViewerDropAdapter:

public final class TaskTransfer extends SimpleObjectTransfer {

public static final TaskTransfer INSTANCE = new TaskTransfer();

private TaskTransfer() {
}

@Override
protected String getTypeNamePrefix() {
    return "TASK_TRANSFER_FORMAT";
}
}

DragSourceListener

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;
}
}

在视图中放置一些类似的代码:

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;
}
}