Setting a custom cursor when dragging an external file into a Swing application

I have a swing application in which I would like to import an external file by dragging an external file from Windows Explorer to the application. I have this basic functionality. However, I would like to change the default mouse cursor icon to the corresponding application cursor. I could not change the cursor visible to the user when the mouse button is pressed and held over the application. I saw examples of this work if the drag operation is in the same swing application. I tried to accomplish this using DragGestureListener and DragSource to no avail. It seems that these methods are not called if the source of resistance is not within the range of oscillation. Is it possible to change the drag and drop cursor while dragging an external file into the swing application?

Please see this simplified example:

public class DnDTemplate extends JFrame { private static final long serialVersionUID = 1L; private JComponent thePane = null; private Cursor dropCursor = null; public DnDTemplate() { super( "Drop File Here" ); thePane = (JComponent) getContentPane(); thePane.setTransferHandler( new DndTransferHandler() ); ImageIcon imageIcon = new ImageIcon( "drop_here.gif" ); Image image = imageIcon.getImage(); BufferedImage bufferedImage = new BufferedImage( 16, 16, BufferedImage.TYPE_INT_ARGB ); Graphics graphics = bufferedImage.getGraphics(); graphics.drawImage( image, 0, 0, null ); dropCursor = Toolkit.getDefaultToolkit().createCustomCursor( bufferedImage, new Point( 16, 16 ), "drop cursor" ); setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); setSize( 300, 300 ); } public static void main( String[] args ) { new DnDTemplate().setVisible( true ); } class DndTransferHandler extends TransferHandler { private static final long serialVersionUID = 1L; @Override public boolean canImport( TransferHandler.TransferSupport info ) { // This gets called repeatedly while dragged file is over frame if ( !info.isDataFlavorSupported( DataFlavor.javaFileListFlavor ) ) { return false; } // Even though this method is called at the appropriate time, // setting the cursor here is of no consequence info.getComponent().setCursor( dropCursor ); return true; } @Override public boolean importData( TransferHandler.TransferSupport info ) { // this gets called when file is dropped if ( !info.isDrop() ) { return false; } Transferable transferable = info.getTransferable(); String importFileName = null; try { List<File> fileList = (List<File>) transferable.getTransferData( DataFlavor.javaFileListFlavor ); Iterator<File> iterator = fileList.iterator(); while ( iterator.hasNext() ) { File f = iterator.next(); importFileName = f.getAbsolutePath(); } info.getComponent().setCursor( dropCursor ); thePane.setCursor( dropCursor ); } catch ( Exception e ) { return false; } System.out.println( "Importing " + importFileName ); // Return the cursor back to the default thePane.setCursor( Cursor.getPredefinedCursor( Cursor.DEFAULT_CURSOR ) ); return true; } } 

}

+7
source share
1 answer

Disclaimer: This was supposed to be a comment, not an answer, but it's too long to fit in the comment. I will delete this answer if it is completely incorrect

I did not test this, but looked at the TransferHandler API. I would suggest TransferHandler#getDragImage look at TransferHandler#getDragImage .

The documentation is a bit unclear as to whether this image is used when initiating drag and drop from a component for which the TransferHandler parameter is set, or is also used when dragging initiation occurs from outside the application and the cursor is set to the component for which TransferHandler is set. I found an example that seems to suggest that this certainly works in a Java application, but is still unconvincing about drag and drop from an external application

Error ID 4816922 suggests using TransferHandler#getVisualRepresentation but it is not clear if the error is fixed.

+1
source

All Articles