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 );
}
}
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");
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With