Java 为什么在setDropTarget()之后不再调用canImport()?
我正在JavaSE7中试验JList的拖放功能。问题是,一旦我为JList设置DropTarget,TransferHandler实现中的canImport()方法就会停止调用。下面是演示该问题的简化代码: 主要类别:Java 为什么在setDropTarget()之后不再调用canImport()?,java,drag-and-drop,Java,Drag And Drop,我正在JavaSE7中试验JList的拖放功能。问题是,一旦我为JList设置DropTarget,TransferHandler实现中的canImport()方法就会停止调用。下面是演示该问题的简化代码: 主要类别: import javax.swing.ListSelectionModel; public class TestDragDrop extends javax.swing.JFrame { public TestDragDrop() { initComp
import javax.swing.ListSelectionModel;
public class TestDragDrop extends javax.swing.JFrame {
public TestDragDrop() {
initComponents();
lstTest.setDragEnabled(true);
lstTest.setTransferHandler(new MyTransferHandler());
// try to comment and uncomment the following line:
lstTest.setDropTarget(new MyDropTarget());
// - commented => canImport() is called during drag gesture
// - uncommented => canImport() is not called during drag gesture
lstTest.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
scroll1 = new javax.swing.JScrollPane();
lstTest = new javax.swing.JList();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
lstTest.setModel(new javax.swing.AbstractListModel() {
String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
public int getSize() { return strings.length; }
public Object getElementAt(int i) { return strings[i]; }
});
scroll1.setViewportView(lstTest);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(scroll1, javax.swing.GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(scroll1, javax.swing.GroupLayout.DEFAULT_SIZE, 174, Short.MAX_VALUE)
.addContainerGap())
);
pack();
}// </editor-fold>
public static void main(String args[]) {
new TestDragDrop().setVisible(true);
}
// Variables declaration - do not modify
private javax.swing.JList lstTest;
private javax.swing.JScrollPane scroll1;
// End of variables declaration
}
我的可转让实施:
import java.awt.datatransfer.Transferable;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.TransferHandler;
public class MyTransferHandler extends TransferHandler {
@Override
public int getSourceActions(JComponent component) {
return COPY_OR_MOVE;
}
@Override
protected Transferable createTransferable(JComponent component) {
if(component instanceof JList) {
return new MyTransferable(new String("TestObject"));
}
return null;
}
@Override
public boolean canImport(TransferHandler.TransferSupport support) {
System.out.println("canImport()");
return true;
}
@Override
public boolean importData(TransferHandler.TransferSupport support) {
System.out.println("importData()");
return true;
}
}
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
public class MyTransferable implements Transferable {
private final Object object;
public MyTransferable(Object object) {
this.object = object;
}
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] { DataFlavor.javaFileListFlavor };
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(DataFlavor.javaFileListFlavor);
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if(!isDataFlavorSupported(flavor)) {
throw new UnsupportedFlavorException(flavor);
}
return object;
}
}
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDropEvent;
public class MyDropTarget extends DropTarget {
@Override
public synchronized void drop(DropTargetDropEvent evt) {
evt.acceptDrop(evt.getDropAction());
if(evt.isLocalTransfer()) {
System.out.println("local transfer");
} else {
System.out.println("extern transfer");
}
evt.dropComplete(true);
}
}
我的drop目标实施:
import java.awt.datatransfer.Transferable;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.TransferHandler;
public class MyTransferHandler extends TransferHandler {
@Override
public int getSourceActions(JComponent component) {
return COPY_OR_MOVE;
}
@Override
protected Transferable createTransferable(JComponent component) {
if(component instanceof JList) {
return new MyTransferable(new String("TestObject"));
}
return null;
}
@Override
public boolean canImport(TransferHandler.TransferSupport support) {
System.out.println("canImport()");
return true;
}
@Override
public boolean importData(TransferHandler.TransferSupport support) {
System.out.println("importData()");
return true;
}
}
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
public class MyTransferable implements Transferable {
private final Object object;
public MyTransferable(Object object) {
this.object = object;
}
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] { DataFlavor.javaFileListFlavor };
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(DataFlavor.javaFileListFlavor);
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if(!isDataFlavorSupported(flavor)) {
throw new UnsupportedFlavorException(flavor);
}
return object;
}
}
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDropEvent;
public class MyDropTarget extends DropTarget {
@Override
public synchronized void drop(DropTargetDropEvent evt) {
evt.acceptDrop(evt.getDropAction());
if(evt.isLocalTransfer()) {
System.out.println("local transfer");
} else {
System.out.println("extern transfer");
}
evt.dropComplete(true);
}
}
如果行lstest.setDropTarget(新的MyDropTarget())在主类中被关闭/注释,MyTransferHandler中的canImport()方法在拖动手势期间被调用。但只要我取消注释这一行,在拖动过程中就不会调用canImport()方法
有人知道为什么不再调用canImport()了吗
非常感谢您的帮助!非常感谢。
设置TransferHandler
如果不存在新的DropTarget
,将安装它以使用指定的TransferHandler
。将此DropTarget
替换为另一个将破坏此设置。将自定义的DropTarget
与以Swing方式工作的TransferHandler
相结合是相当棘手的。以下内容将完成此工作:
jComponent.setTransferHandler(new MyTransferHandler());
DropTarget original = jComponent.getDropTarget();// the Swing DropTarget
MyDropTarget myDropTarget = new MyDropTarget();
myDropTarget.addDropTargetListener(original);// delegate for original behavior
jComponent.setDropTarget(myDropTarget);
你好,霍尔格。谢谢你的回答。我试图更改方法调用setTransferHandler()和setDropTarget()的顺序,但没有成功。子系统仍然没有调用函数canImport()。还有什么建议吗?是的,我刚刚发现,如果存在自定义
DropTarget
,则setTransferHandler
什么也不做。我修正了答案。太好了,现在它可以正常工作了。非常感谢霍尔格!