1

I want to make a Java swing label (containing text) draggable so it can be dropped into a browser window (where a js listener picks up the text). Making it draggable is easy enough but how to transfer it to the browser window?

I've been searching for documentation on this but most of what I found is from long ago like this (from 1999!):

http://www.javaworld.com/article/2076358/swing-gui-programming/how-to-drag-and-drop-with-java-2--part-1.html

  • 1
    Possible duplicate of [How to Access Dragged Text (Or: How Does Dragging Text into an Input "Work"?)](https://stackoverflow.com/questions/24808217/how-to-access-dragged-text-or-how-does-dragging-text-into-an-input-work) – Kh.Taheri Aug 01 '17 at 12:48

1 Answers1

0

Here is a small example of how you can extend TransferHandler to drag text from a JLabel (or any other component) into other running applications:

import javax.swing.*;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

/**
 * @author Mikle Garin
 * @see https://stackoverflow.com/questions/45437809/drag-and-drop-text-from-java-to-web-browser
 */

public class TextDragHandler extends TransferHandler implements MouseListener, MouseMotionListener
{
    /**
     * Drag source component.
     */
    private final JComponent component;

    /**
     * Text to drag.
     */
    private final String text;

    /**
     * Whether or not drag was armed.
     * This flag is used to avoid multiple export operations.
     */
    private boolean armed;

    /**
     * Constructs new {@link TextDragHandler}.
     *
     * @param component drag source component
     * @param text      text to drag
     */
    public TextDragHandler ( final JComponent component, final String text )
    {
        super ();
        this.armed = false;
        this.text = text;
        this.component = component;
        this.component.addMouseListener ( this );
        this.component.addMouseMotionListener ( this );
    }

    @Override
    public void mouseClicked ( final MouseEvent e )
    {
        // Do nothing
    }

    @Override
    public void mousePressed ( final MouseEvent e )
    {
        if ( component.isEnabled () && SwingUtilities.isLeftMouseButton ( e ) )
        {
            armed = true;
        }
    }

    @Override
    public void mouseReleased ( final MouseEvent e )
    {
        if ( SwingUtilities.isLeftMouseButton ( e ) )
        {
            armed = false;
        }
    }

    @Override
    public void mouseEntered ( final MouseEvent e )
    {
        // Do nothing
    }

    @Override
    public void mouseExited ( final MouseEvent e )
    {
        // Do nothing
    }

    @Override
    public void mouseMoved ( final MouseEvent e )
    {
        // Do nothing
    }

    @Override
    public void mouseDragged ( final MouseEvent e )
    {
        if ( armed )
        {
            exportAsDrag ( component, e, getSourceActions ( component ) );
            armed = false;
        }
    }

    @Override
    public int getSourceActions ( final JComponent c )
    {
        return COPY;
    }

    @Override
    protected Transferable createTransferable ( final JComponent c )
    {
        return new StringSelection ( text );
    }

    /**
     * Sample {@link TextDragHandler} usage.
     *
     * @param args run arguments
     */
    public static void main ( final String[] args )
    {
        final JFrame frame = new JFrame ( "Drag example" );

        final JLabel label = new JLabel ( "DRAG ME" );
        label.setTransferHandler ( new TextDragHandler ( label, label.getText () ) );
        label.setBorder ( BorderFactory.createEmptyBorder ( 50, 50, 50, 50 ) );
        frame.add ( label );

        frame.setDefaultCloseOperation ( WindowConstants.EXIT_ON_CLOSE );
        frame.pack ();
        frame.setLocationRelativeTo ( null );
        frame.setVisible ( true );
    }
}

The most important thing here is the exportAsDrag ( ... ) call which initiates the drag operation within the system and passes your Transferable instance (in this case - StringSelection instance) into that drag operation.

Mikle Garin
  • 10,083
  • 37
  • 59
  • @Garin have you noticed the lag while attempting a drop into firefox? – karuhanga Jun 17 '18 at 22:42
  • @Karuhanga You mean when dragging text from the example above? - don't really see any lag there, just checked with the latest FF. Although it is important to understand that whenever you start such drag operation - handling it is up to the underlying OS and the application you drop data onto. Meaning different combinations of OS/software can give completely different results. As an drag "exporter" you can only provide various supported data flavors and data for them, you cannot directly affect the drag operation itself. – Mikle Garin Jun 18 '18 at 15:35
  • @Karuhanga So for instance some Linux versions have issues with D&D and system UI manager can even freeze completely due to some specific D&D attempts. Windows 8 has issues with dropping onto Java applications depending on system user permissions. Mac OS X also has some issues depending on JDK/OS version. So I'm not really surprised that you are encountering some D&D issues under your specific circumstances :) – Mikle Garin Jun 18 '18 at 15:39
  • I see. I've had the problem with Firefox on Ubuntu 16.04. I guess I'll try with windows and see if it is the same. And yes, I've tried it with both text and images and Firefox seems to react slower than chrome to the `dragover` event. Thanks though. – karuhanga Jun 18 '18 at 23:18