2011-02-03 12 views
12

O.Reilly-Swing.Hacks Hack 69. Translucent Drag-and-Drop'dan bir önizlemeyle basit bir JComponent-Sürükle ve Bırak özelliğini gerçekleştirmek istiyorum. Benim Sorunum, TransferHandler MouseDragged() MouseMotionListener işlemini durdurma işlemini başlatırsa).Neden DragHandler exportAsDrag MouseMotionListener'ı devre dışı bırakıyor?

İşte biraz örnek koddur:

yeşil ve kırmızı Side ile küçük pencere. Yeşil Taraf bir Sürükle başlatılamıyor, her zaman mouseDragged() gerçekleştiriliyor ancak exportDone() öğesine asla ulaşılamıyor.

Kırmızı Taraf, exportAsDrag() yoluyla bir Sürükle başlatır, ancak bundan sonra mouseDragged() artık çalışmayacaktır.

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

}

+0

"Artık çalışmayacak" üzerine genişleyebilir misiniz? – jzd

+0

örnekte: Konsolda – oliholz

cevap

5

Sürükleme eylemini başlattıktan sonra, hareket olayı normal fare sürükleme olayı olarak gönderilmez. Sürüklerken, fare hareket ettiğinde bir DragSourceDragEvent tetiklenir. Aşağıdaki örnek, kırmızı alan sürüklendiğinde "DRAGMOUSEMOVED" yazdıracaktır. Aşağıdaki kaynağı yapıcınıza yapıştırın. DragSourceDragEvent, MouseEvent yöntemlerinin çoğuna sahiptir, bu yüzden iyi bir alternatif olmalıdır.

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

Değişim bu satırı:

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

için:

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

Sana beklediklerini davranışı gördüğünü yaptılar ("çekilir" basılmış "İHRACAT" dan sonra konsol.

+0

baskısı çıkmıyor "Aktarım eylemi" COPY veya MOVE değeri olmalıdır, aksi halde "sürükleme olarak dışa aktarılmaz". DropTarget'im Transfer Nesnesini kabul etmek zorunda. – oliholz

+0

Herhangi bir nedenle, aynı değeri kullanmak için 'getSoureActions' ve' exportAsDrag' yöntemlerini eşleştirdiğimde, sürükleme olayı doğru olarak verilmez. 'LINK''i döndürmek için' getSourceActions' yöntemini değiştirmeyi deneyin veya 'exportAsDrag' yönteminde' TransferHandler.LINK 'göndermeyi deneyin. DropTarget'in Transferi Nesnesini kabul etmesine izin verecek mi? – bamana

+0

'LINK' DropTarget’i kabul etmesine izin verin, ancak MouseMotionListener da mouseDragged() işlemini durdurur. – oliholz