2012-12-05 4 views
2

JPanel을 사용하여 캔버스에 개체를 끌 수있는 사용자 지정 캔버스 스타일 구성 요소를 정의했습니다. 내가 알아낼 수없는 것은 TransferHandler를 사용하여 드래그 앤 드롭 (DnD) 커서를 맞춤형 커서로 변경하는 방법입니다. 예를 들어, DnD 중에 기본 링크 커서 대신 내 자신을 대체하고 싶습니다. TransferHandler를 사용해 이것을 실시하는 방법이 있습니까?자바 드래그 앤 드롭 맞춤 커서

필자는 AWT DnD 지원을 사용해야한다고 생각합니다.하지만 가능한 경우이를 피하려고합니다.

답변

1

TransferHandler 코드를 파헤 치면 해결할 수있는 것이 발견되었습니다. dragOver 메서드는 커서를 변경하는 곳입니다. 나는 여전히 내가 누락 될 수 있다고 생각하지만 지금은 효과가있을 것이다.

두 개의 정적 클래스와 exportAsDrag의 코드는 TransferHandler 소스의 코드 사본을 약간 수정 한 것입니다.

편집 -이 방법을 사용해 보았습니다. 희망이 도움이됩니다. 제안을 환영합니다.

public class OverrideIconTransferHandler extends TransferHandler { 
    private class MyDragGestureRecognizer extends DragGestureRecognizer { 

     private static final long serialVersionUID = 1L; 

     MyDragGestureRecognizer(DragGestureListener dgl) { 
      super(DragSource.getDefaultDragSource(), null, NONE, dgl); 
     } 

     void gestured(JComponent c, MouseEvent e, int srcActions, int action) { 
      setComponent(c); 
      setSourceActions(srcActions); 
      appendEvent(e); 
      fireDragGestureRecognized(action, e.getPoint()); 
     } 

     @Override 
     protected void registerListeners() { 
     } 

     @Override 
     protected void unregisterListeners() { 
     } 

    } 

    private class MyDragHandler implements DragGestureListener, DragSourceListener { 

     private boolean scrolls; 

     @Override 
     public void dragDropEnd(DragSourceDropEvent dsde) { 
      DragSourceContext dsc = dsde.getDragSourceContext(); 
      JComponent c = (JComponent) dsc.getComponent(); 
      if (c.getTransferHandler() instanceof OverrideIconTransferHandler) { 
       OverrideIconTransferHandler t = (OverrideIconTransferHandler) c.getTransferHandler(); 
       if (dsde.getDropSuccess()) { 
        t.exportDone(c, dsc.getTransferable(), dsde.getDropAction()); 
       } else { 
        t.exportDone(c, dsc.getTransferable(), NONE); 
       } 
      } 
      c.setAutoscrolls(scrolls); 
     } 

     @Override 
     public void dragEnter(DragSourceDragEvent dsde) { 
     } 

     @Override 
     public void dragExit(DragSourceEvent dsde) { 
     } 

     @Override 
     public void dragGestureRecognized(DragGestureEvent dge) { 
      JComponent c = (JComponent) dge.getComponent(); 
      if (c.getTransferHandler() instanceof OverrideIconTransferHandler) { 
       OverrideIconTransferHandler th = (OverrideIconTransferHandler) c.getTransferHandler(); 
       Transferable t = th.createTransferable(c); 
       if (t != null) { 
        scrolls = c.getAutoscrolls(); 
        c.setAutoscrolls(false); 
        try { 
         Image im = th.getDragImage(); 
         if (im == null) { 
          dge.startDrag(null, t, this); 
         } else { 
          dge.startDrag(null, im, th.getDragImageOffset(), t, this); 
         } 
         return; 
        } catch (RuntimeException re) { 
         c.setAutoscrolls(scrolls); 
        } 
       } 

       th.exportDone(c, t, NONE); 
      } 
     } 

     @Override 
     public void dragOver(DragSourceDragEvent dsde) { 
      if (dropCursorOverrides.containsKey(dsde.getDropAction())) { 
       dsde.getDragSourceContext().setCursor(dropCursorOverrides.get(dsde.getDropAction())); 
      } else { 
       dsde.getDragSourceContext().setCursor(null); 
      } 
     } 

     @Override 
     public void dropActionChanged(DragSourceDragEvent dsde) { 
     } 
    } 

    private static final long serialVersionUID = 1L; 
    private MyDragGestureRecognizer myRecognizer = null; 
    private final Map<Integer, Cursor> dropCursorOverrides = new HashMap<>(); 

    public void addDropCursorOverride(final int action, final Cursor cursor) throws IllegalArgumentException { 
     if (!(action == COPY || action == MOVE || action == LINK || action == NONE)) { 
      throw new IllegalArgumentException("Unknown Action Type"); 
     } 
     dropCursorOverrides.put(action, cursor); 
    } 

    @Override 
    public void exportAsDrag(JComponent comp, InputEvent e, int action) { 
     if (comp.getTransferHandler() instanceof OverrideIconTransferHandler) { 
      int srcActions = getSourceActions(comp); 

      if (!(e instanceof MouseEvent) || !(action == COPY || action == MOVE || action == LINK) || (srcActions & action) == 0) { 

       action = NONE; 
      } 

      if (action != NONE && !GraphicsEnvironment.isHeadless()) { 
       if (myRecognizer == null) { 
        myRecognizer = new MyDragGestureRecognizer(new MyDragHandler()); 
       } 
       myRecognizer.gestured(comp, (MouseEvent) e, srcActions, action); 
      } else { 
       exportDone(comp, null, NONE); 
      } 
     } else { 
      super.exportAsDrag(comp, e, action); 
     } 
    } 

    public void removeDropCursorOverride(final int action) throws IllegalArgumentException { 
     if (!(action == COPY || action == MOVE || action == LINK || action == NONE)) { 
      throw new IllegalArgumentException("Unknown Action Type"); 
     } 
     dropCursorOverrides.remove(action); 
    } 
}