为啥 DragHandler exportAs Drag 禁用了我的 MouseMotionListener?

Posted

技术标签:

【中文标题】为啥 DragHandler exportAs Drag 禁用了我的 MouseMotionListener?【英文标题】:Why DragHandler exportAsDrag disables my MouseMotionListener?为什么 DragHandler exportAs Drag 禁用了我的 MouseMotionListener? 【发布时间】:2011-06-20 16:15:22 【问题描述】:

我想通过 O.Reilly-Swing.Hacks Hack 69. Translucent Drag-and-Drop 的预览来实现一个简单的 JComponent-Drag-and-Drop。 我的问题是如果 TransferHandler 开始拖动 MouseMotionListener 停止执行 mouseDragged()。

这是一个小示例代码:

一个带有绿色和红色侧面的小窗口。 绿边不开始拖动,总是执行 mouseDragged() 但永远不会到达 exportDone()。

红方通过 exportAsDrag() 开始拖动,但之后 mouseDragged() 将不再起作用。

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 );

【问题讨论】:

你能扩展“将不再工作”吗? 在示例中:我在控制台上没有打印出“拖动” 【参考方案1】:

开始拖动动作后,运动事件将不会作为普通的鼠标拖动事件进行调度。在拖动过程中,当鼠标移动时会触发 DragSourceDragEvent。以下示例将在拖动红色区域时打印“DRAGMOUSEMOVED”。只需将下面的源代码粘贴到您的构造函数中。 DragSourceDragEvent 具有大部分 MouseEvent 方法,因此它应该是一个不错的选择。

DragSource.getDefaultDragSource().addDragSourceMotionListener(new DragSourceMotionListener() 
    @Override
    public void dragMouseMoved(DragSourceDragEvent dsde) 
        System.out.println("DRAGMOUSEMOVED");
    
);

【讨论】:

【参考方案2】:

改变这一行:

this.getTransferHandler().exportAsDrag( this, e, TransferHandler.MOVE );

到:

this.getTransferHandler().exportAsDrag( this, e, TransferHandler.NONE );

当我这样做时,我看到了您所期望的行为(“导出”之后的“拖动”打印到控制台)。

【讨论】:

传输动作应该是COPY或MOVE的值,否则它不会'export as drag'。我的 DropTarget 必须接受 Transfer-Object。 由于某种原因,每当我匹配 getSoureActionsexportAsDrag 方法以使用相同的值时,拖动事件都不会正确导出。尝试将getSourceActions 方法更改为返回LINK 或尝试发送TransferHandler.LINK' in the exportAsDrag` 方法。这会允许 DropTarget 接受 Transfer-Object 吗? LINK 让 DropTarget 接受,但 MouseMotionListener 也停止执行 mouseDragged()。 它不能解决我的问题。我观察到LINKMOVECOPY 有类似的行为。我不知道为什么 MouseMotionListener-Method 'mouseDragged' 会停止。如果 (action != NONE) SwingDragGestureRecognizer.gestured() 将触发DragGestureRecognized,之后我不再收到 mouseDragged 调用。也许我需要阅读一本好的“编写你自己的 DragGestureRecognizer”-Tutorial 抱歉,我无法提供更多帮助。希望你能尽快得到它。

以上是关于为啥 DragHandler exportAs Drag 禁用了我的 MouseMotionListener?的主要内容,如果未能解决你的问题,请参考以下文章

Angular2 问题:没有将“exportAs”设置为“ngForm”的指令

没有将“exportAs”设置为“ngForm”的指令

Angular/NgForm/NgModel 指令错误:没有将“exportAs”设置为“ngForm”的指令

Angular 4中的模板解析错误“没有将exportAs设置为ngModel的指令”

powershell Lista grupos y usuarios de unsitioespecíficoenSharePoint y los exporta a un csv

QML 指针处理程序和处理抓取更改