2

I have multi-window java swing application with drag&drop between windows support.

I'd like to change mouse cursor globally even if it is between application windows.

The most obvious solution which is Component.setCursor() called on component which starts drag or on the main window does not work.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Wojciech Wirzbicki
  • 3,887
  • 6
  • 36
  • 59
  • *"Is it possible to change mouse pointer (Cursor) from swing when mouse is outside application window?"* Only using natives. @f1sh What was the search term? Was the solution specific to Java? – Andrew Thompson Apr 06 '16 at 09:33
  • @f1sh *"..set the position of the mouse in Java?"* O_o You should have spent more time reading the question.. – Andrew Thompson Apr 06 '16 at 09:34
  • @AndrewThompson why, what's wrong with the linked question? Are you telling me using ``Robot`` does not enable you do move the mouse in java? – f1sh Apr 06 '16 at 09:36
  • 1
    I want to change the type of the cursor not position. – Wojciech Wirzbicki Apr 06 '16 at 09:38
  • 1
    @f1sh No, I'm saying the question is not asking about moving the pointer, it is about setting the cursor (the image) the pointer uses. The 'drag cursor' appears different to a normal pointer. – Andrew Thompson Apr 06 '16 at 09:38
  • You are both correct. I am an idiot. – f1sh Apr 06 '16 at 09:39
  • I edited the question beacause it wasn't clear enough. – Wojciech Wirzbicki Apr 06 '16 at 09:40
  • I'm going to suggest a different approach that makes the question irrelevant: a Multi-Document Interface instead of different windows. Implement it using `JDesktopPane`/`JInternalFrame`s and the mouse never needs to leave the app. See also [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) – Andrew Thompson Apr 06 '16 at 09:43
  • 1
    It depend a lot on how and what you are doing, for example, if your deep in the bowels of the API, using the low level d'n'd API, then you specify the drag cursor when calling [DragGestureEvent#startDrag](https://docs.oracle.com/javase/8/docs/api/java/awt/dnd/DragGestureEvent.html#startDrag-java.awt.Cursor-java.awt.Image-java.awt.Point-java.awt.datatransfer.Transferable-java.awt.dnd.DragSourceListener-), but it's not support on all systems. The newer transfer API hides all that behind private functionality - awesome :P – MadProgrammer Apr 06 '16 at 10:06
  • 1
    Related question about changing mouse cursor using JNI: http://stackoverflow.com/questions/6220810/trying-to-change-windows-mouse-cursor-icon-from-java-through-jni-call – tak3shi Apr 06 '16 at 11:12
  • Its only an idea: Is it possible to draw an invisible JDialog or similar component over the whole desktop (max size), while dragging? – tak3shi Apr 06 '16 at 11:45
  • Yes, this is possible but I have another problem with this approach: http://stackoverflow.com/questions/36130906/transparent-jdialog-becomes-opaque-when-dragging-to-second-screen-ubuntu-14-04 – Wojciech Wirzbicki Apr 06 '16 at 11:58
  • *"Yes, this is possible.."* Who are you replying to? Tip: Add @tak3shi (or whoever, the `@` is important) to *notify* the person of a new comment. – Andrew Thompson Apr 06 '16 at 23:25

1 Answers1

2

Then only way I found to do this without using native, platform-dependent api is to use java Swing's DnD api which allows You to set custom mouse cursor when dragging

import javax.swing.*;

import java.awt.Cursor;
import java.awt.datatransfer.StringSelection;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;

public class DndExample extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new DndExample());
    }

    public DndExample() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JLabel dragLabel = createDndLabel();
        getContentPane().add(dragLabel);
        pack();
        setVisible(true);
    }

    private JLabel createDndLabel() {
        JLabel label = new JLabel("Drag me, please");


        DragGestureListener dragGestureListener = (dragTrigger) -> {
            dragTrigger.startDrag(new Cursor(Cursor.HAND_CURSOR), new StringSelection(label.getText()));
        };

        DragSource dragSource = DragSource.getDefaultDragSource();
        dragSource.createDefaultDragGestureRecognizer(label, DnDConstants.ACTION_COPY, dragGestureListener);

        return label;
    }
}
Wojciech Wirzbicki
  • 3,887
  • 6
  • 36
  • 59