Java拖放自定义光标

时间:2012-12-05 17:33:58

标签: java swing jpanel drag-and-drop java-canvas

我使用JPanel定义了一个自定义画布样式组件,它将支持将对象拖动到画布上。我似乎无法弄清楚如何使用TransferHandler将拖放(DnD)光标更改为自定义光标。例如,代替DnD期间的默认链接光标,我想替换我自己的。有没有办法使用TransferHandler?

我怀疑我将不得不使用AWT DnD支持来做到这一点,但我希望如果可以的话就避免这样做。

1 个答案:

答案 0 :(得分: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);
    }
}