Java drag and drop custom cursor

筅森魡賤 提交于 2019-12-08 00:37:18

问题


I have defined a custom canvas style component, using JPanel, that will support the dragging of objects onto the canvas. What I can't seem to figure out is how to change the drag and drop (DnD) cursor to a custom one, using a TransferHandler. For example, instead of the default link cursor during DnD, I want substitute my own. Is there a way to do this using a TransferHandler?

I suspect I will have to use the AWT DnD support to do this but I am hoping to avoid that if I can.


回答1:


By digging into the TransferHandler code I found a work around. The dragOver method is where I change the cursor. I still think I may be missing something simple but this will work for now.

The two static class, as well as the code in the exportAsDrag are minorly modified copies of code from the TransferHandler source.

EDIT - This is how I worked it out. Hope this helps. Suggestions welcome.

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


来源:https://stackoverflow.com/questions/13729078/java-drag-and-drop-custom-cursor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!