java - 通过拖放重新排序表行?

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

我是 Eclipse RCP/插件和 SWT 新手。我想通过拖放对表格项目重新排序。

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

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

最佳答案

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

我使用了 Spring 的 BeanUtils 类,但您可以使用任何可以深度复制 POJO 的库(或编写您自己的库)。我假设您的 ITask 有一个 setOrder(int) 方法并且是可序列化的(并且它符合 POJO 的资格)

您需要为您的 ITask 创建一个 Transfer-type:SimpleObjectTransfer 是 IBM 的代码,来自 Eclipse GEF。您可以通过 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;
}
}

并在您的 View 中放置类似于以下的代码:

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

关于java - 通过拖放重新排序表行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37275552/

相关文章:

drag-and-drop - 如何拖放自定义小部件?

c# - 如何在按钮上触发 "DragStarting"事件?

php - 在 div 容器中启用拖放上传

java - 如何将 stanford coreNLP 服务器部署到在线 Web 服务,例如赫鲁库?

java - getIntent().getByteArrayExtra() 返回 null

java - 从另一个 fragment 返回后如何防止 fragment 刷新recyclerview/保存recyclerview位置

sql - 免费的 SQL 格式化工具

python - 如何将 Python.h 库添加到 Eclipse 以在 C++ 程序中使用?

java - SSL 握手异常 :no cipher suites in common

java - 如何为eclipse插件项目创建一个jar文件,该文件应该能够在没有eclipse软件的情况下下载和运行?