2017-10-24 1 views
0

드롭 대상으로 테이블을 가져 오려는 이유는 실제로 아이템을 떨어 뜨린 위치와 관련이 있기 때문입니다. 따라서 사용자는 이미 드래그를 시작한 후에 보이는 항목을 재조정 할 수 있습니다.드래그시 스크롤 테이블

누락 된 기본 동작은 다음과 같습니다. 마지막으로 표시된 행 위로 마우스를 이동하고 테이블을 아래로 스크롤합니다. 첫 번째 표시 줄 위로 마우스를 가져간 다음 위로 스크롤합니다.

그래서 사용자가 테이블 중앙으로 가리키면 아이콘을 스크롤하기 위해 노력하고있어 어떤 내가 지금하고 있어요 :

작은 사람을위한
final Display display = new Display(); 
    final Shell shell = new Shell(display); 
    shell.setLayout(new GridLayout()); 

    // drag source: the label 

    final Label label = new Label(shell, SWT.NONE); 
    label.setText("Drag from me!"); 
    label.setDragDetect(true); 
    label.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); 

    final DragSource source = new DragSource(label, DND.DROP_MOVE | DND.DROP_COPY); 
    source.setTransfer(new Transfer[]{TextTransfer.getInstance()}); 
    source.addDragListener(new DragSourceAdapter() { 
     @Override 
     public void dragSetData(DragSourceEvent event) { 
      event.data = label.getText(); 
     } 
    }); 

    // drop target: the viewer 

    final TableViewer viewer = new TableViewer(shell, 
      SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); 
    viewer.setContentProvider(ArrayContentProvider.getInstance()); 
    viewer.setLabelProvider(new ColumnLabelProvider()); 
    viewer.setInput(IntStream.range(1, 100).mapToObj(String::valueOf).collect(Collectors.toList())); 
    viewer.getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).hint(100, 100).create()); 

    final DropTarget target = new DropTarget(viewer.getTable(), DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT); 
    target.setTransfer(new Transfer[]{TextTransfer.getInstance()}); 
    target.addDropListener(new DropTargetAdapter() { 

     private static final int TIME_BETWEEN_MOVEMENTS = 700; 
     private long lastMovementTime; 

     @Override 
     public void dragOver(DropTargetEvent event) { 
      final Table table = viewer.getTable(); 
      final TableItem item = table.getItem(table.toControl(new Point(event.x, event.y))); 
      if (item != null) { 
       final long currentTime = System.currentTimeMillis(); 
       if (currentTime > this.lastMovementTime + TIME_BETWEEN_MOVEMENTS) { 
        table.setTopIndex(Math.max(0, table.indexOf(item) - getVisibleItems(table)/2)); 
        this.lastMovementTime = currentTime; 
       } 
       table.setSelection(item); 
      } 
     } 

     private int getVisibleItems(Table table) { 
      return (table.getClientArea().height - table.getHeaderHeight())/table.getItemHeight(); 
     } 
    }); 

    // open everything 

    shell.pack(); 
    shell.open(); 

    while (!shell.isDisposed()) { 
     if (!display.readAndDispatch()) { 
      display.sleep(); 
     } 
    } 
    display.dispose(); 
키가 큰 테이블에 대한 신속

이 스크롤이 아니라, 그래서 내가 사용하고있는 대부분의 소프트웨어에서 매우 일반적인 사용 사례이기 때문에 더 좋은 방법이 있는지 궁금합니다.

어떻게 드래그하는 동안 테이블을 스크롤합니까?

+1

여기서 달성하고자하는 것을 이해하는 데 어려움을 겪고 있습니다. 드래그하는 동안 (마우스 휠을 사용하여) 테이블을 스크롤 할 수 있기를 원하십니까? 또는 드래그 할 때 테이블을 자동으로 스크롤하여 가장자리에 도달하게 하시겠습니까? – Baz

+0

@Baz 가장자리에 도달하면 스크롤하고 싶습니다. 마우스 휠 비트는 SWT에서 테이블 위로 드래그하는 동안 스크롤이 지원되지 않는다는 것을 보여줍니다. –

+2

참고 : Excel은 드래그하는 동안 마우스 휠 스크롤을 수행하지 않습니다. 전체 프레임 워크를 "멍청한"전체 프레임 워크라고 부르면 안됩니다. 왜냐하면 자신이해야한다고 생각하는 것을하지 않기 때문입니다. – Baz

답변

2

좋아, 내가 조금 실험하고 적어도 당신에게 좋은 출발점을 제공해야 해결책을 생각해 냈어. 그것이하는 일은 다양한 마우스 이벤트를 듣고 선택한 항목을 기억합니다. 가장자리 (상단 또는 하단)에 도달하면 테이블을 하나의 항목만큼 위/아래로 움직입니다.

private static boolean dragging = false; 
private static int  start = -1; 
private static int  end  = -1; 

public static void main(String[] args) 
{ 
    final Display display = new Display(); 
    final Shell shell = new Shell(display); 
    shell.setLayout(new FillLayout()); 

    List<String> input = IntStream.range(1, 100) 
            .mapToObj(String::valueOf) 
            .collect(Collectors.toList()); 

    final TableViewer viewer = new TableViewer(shell, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); 
    viewer.setContentProvider(ArrayContentProvider.getInstance()); 
    viewer.setLabelProvider(new ColumnLabelProvider()); 
    viewer.setInput(input); 

    Table table = viewer.getTable(); 
    // Stop dragging when the mouse is released 
    table.addListener(SWT.MouseUp, e -> dragging = false); 
    // Start dragging when the mouse is clicked 
    table.addListener(SWT.MouseDown, e -> { 
     dragging = true; 
     start = -1; 
     end = -1; 
    }); 
    // Listen to mouse movement 
    table.addListener(SWT.MouseMove, e -> { 
     // If we're currently dragging 
     if (dragging) 
     { 
      // Get the item under the mouse pointer 
      TableItem item = table.getItem(new Point(e.x, e.y)); 

      if(item != null) 
      { 
       int current = table.indexOf(item); 

       // If this is the first selected item, remember the position 
       if (start == -1 && end == -1) 
       { 
        start = current; 
        end = current; 
       } 
       // Else, just remember the "end" of the drag 
       else 
        end = current; 

       // Tell the viewer to select the items 
       viewer.setSelection(new StructuredSelection(input.subList(Math.min(start, end), Math.max(start, end)))); 

       // Now, we actually move the table when the drag movement reaches the top or bottom 
       int tableHeight = table.getClientArea().height; 
       int itemHeight = table.getItemHeight(); 

       if (e.y < itemHeight && current > 0) 
        table.showItem(table.getItem(current - 1)); 
       else if (e.y > tableHeight - itemHeight && current < table.getItemCount() - 1) 
        table.showItem(table.getItem(current + 1)); 
      } 
     } 
    }); 

    shell.pack(); 
    shell.open(); 
    shell.setSize(400, 300); 

    while (!shell.isDisposed()) 
    { 
     if (!display.readAndDispatch()) 
     { 
      display.sleep(); 
     } 
    } 
    display.dispose(); 
}