2016-05-17 3 views
1

Я новичок в Eclipse RCP/Plug-ins и SWT. Я хочу переупорядочить элементы таблицы с помощью перетаскивания.Изменить порядок строк таблицы с помощью Drag-and-Drop?

У меня есть TableViewer, который содержит таблицу с моими пользовательскими элементами типа ITask (каждый из моих пользовательских элементов завернут в TableItem). Все учебники, которые я нашел, касаются деревьев или перетаскивания между разными таблицами, которые мне не нужны.

Так что я хочу знать, как изменить порядок строк таблицы с помощью перетаскивания.

+0

Http: //www.java2s .com/Tutorial/Java/0280__SWT/DragandDropinsideTable.htm – SomeDude

+0

Являются ли ваши TableItems простыми текстами или POJO? Если ITask реализован POJO-s, связанный пример вам не подходит. –

+0

@AdamHorvath Мои элементы ITask - это не просто простые текстовые элементы. Они имеют поля имен строк, которые показаны в таблице, чтобы пользователь мог их видеть, но на самом деле они содержат алгоритмы и другие важные поля. – Nicholas

ответ

0

Это немного длинный, но вы можете сделать эту работу в своем коде с несколькими изменениями. Я не включил импорт; Eclipse может сделать это автоматически.

Я использовал класс Spring BeanUtils, но вы можете использовать любую библиотеку lib (или написать свой собственный), которая может обрабатывать POJO. Я полагаю, что ваш ITask имеет метод setOrder (int) и является Serializable (и он подходит для POJO)

Вам необходимо создать тип передачи для вашего ITask: 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; 
} 
} 

И поместить код несколько, как это в вашем Вид:

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

Благодарим вас за ответ. Могу ли я использовать 'LocalSelectionTransfer' вместо того, чтобы создавать свой собственный тип переноса? – Nicholas

Смежные вопросы