Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why DragHandler exportAsDrag disables my MouseMotionListener?

I want to realize a simple JComponent-Drag-and-Drop with a preview from O.Reilly-Swing.Hacks Hack 69. Translucent Drag-and-Drop. My Problem is if the TransferHandler start the Drag the MouseMotionListener stop performing mouseDragged().

Here is a little Sample code:

A small Window with a green and a red Side. The green Side do not start a Drag, always mouseDragged() is performed but the exportDone() will never reached.

The red Side starts a Drag via exportAsDrag(), but after that the mouseDragged() will not work anymore.

public class Drag extends JPanel implements Transferable, MouseMotionListener, MouseListener {
public Drag() {
    this.setTransferHandler( new TransferHandler() {
        @Override
        protected Transferable createTransferable( JComponent c ) {
            return (Drag)c;
        }
        @Override
        public boolean canImport( JComponent comp, DataFlavor[] transferFlavors ) {
            return false;
        }
        @Override
        public int getSourceActions( JComponent c ) {
            return MOVE;
        }
        @Override
        protected void exportDone( JComponent source, Transferable data, int action ) {
            super.exportDone( source, data, action );
            System.out.println( "done" );
        }
    } );
    this.setPreferredSize( new Dimension( 200, 100 ) );
    this.addMouseMotionListener( this );
    this.addMouseListener( this );
}
@Override
public void mouseDragged( MouseEvent e ) {
    System.out.println( "drag" );
}
@Override
public void mouseMoved( MouseEvent e ) { }
@Override
public void mousePressed( MouseEvent e ) {
    if( e.getX() > getWidth() / 2 ) {
        System.out.println( "EXPORT" );
        this.getTransferHandler().exportAsDrag( this, e, TransferHandler.MOVE );
    } else {
        System.out.println( "no Export" );
    }
}
@Override
public void paint( Graphics g ) {
    super.paint( g );
    g.setColor( Color.GREEN );
    g.fillRect( 0, 0, getWidth() / 2, getHeight() );
    g.setColor( Color.RED );
    g.fillRect( getWidth() / 2, 0, getWidth(), getHeight() );
}
public boolean isDataFlavorSupported( DataFlavor flavor ) {
    return false;
}
public DataFlavor[] getTransferDataFlavors() {
    return new DataFlavor[] {};
}
public Object getTransferData( DataFlavor flavor ) throws UnsupportedFlavorException, IOException {
    return new Object();
}
@Override
public void mouseClicked( MouseEvent e ) { }
@Override
public void mouseEntered( MouseEvent e ) { }
@Override
public void mouseExited( MouseEvent e ) { }
@Override
public void mouseReleased( MouseEvent e ) { }

static public void main( String[] s ) {
    JFrame f = new JFrame();
    f.setSize( 200, 200 );
    f.getContentPane().setLayout( new BorderLayout() );
    Drag d = new Drag();
    f.getContentPane().add( d, BorderLayout.NORTH );
    f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    f.setVisible( true );
}

}

like image 265
oliholz Avatar asked Feb 03 '11 13:02

oliholz


1 Answers

After starting the drag action, the motion event won't be dispatched as a normal mouse drag event. During the dragging, a DragSourceDragEvent is fired when the mouse moves. The following example will print "DRAGMOUSEMOVED" when the red area is dragged. Just paste the source below into your constructor. The DragSourceDragEvent has most of the MouseEvent methods, so it should be a good alternative.

DragSource.getDefaultDragSource().addDragSourceMotionListener(new DragSourceMotionListener() {
    @Override
    public void dragMouseMoved(DragSourceDragEvent dsde) {
        System.out.println("DRAGMOUSEMOVED");
    }
});
like image 122
André Avatar answered Oct 24 '22 10:10

André