更新/状态:错误已报告给 Oracle,目前仍处于打开状态/未解决:https ://bugs.openjdk.java.net/browse/JDK-8054325
我发现了一个奇怪的错误,它只出现在 OS X 上的 Java 7 和 8 上,而不是 Java 6 和 Java 7 Windows 上。
下面是提取的错误,尽可能多地删除不需要的代码。它给我们留下了一个小表格和一个按钮,我们可以将单元格从按钮顶部的表格中拖动出来。
在我们的生产代码中,我们使用的TransferHandler
是COPY_OR_MOVE
作为源操作的。我们有两个目标,一个DropTarget
接受 as MOVE
,另一个接受 as COPY
。似乎在 OS X 上 JDK/JRE 被破坏了,因为如果它报告的DropTarget
接受是.COPY
TranferHandler
MOVE
如果我们在 Java 6(或 Windows 上的 Java 7)上执行下面的代码,它会报告(如预期的那样):
not move
is copy
但是当我们在 OS X Java 7 或 Java 8 上执行它时,我们会得到以下结果:
is move
not copy
我已经对此进行了测试并将其报告给了 Oracle(错误报告仍在等待中)。但是由于这需要(很长)一段时间才能得到解决,也许这里有人对如何做出“干净”的解决方法有想法?
我宁愿不将放置目标链接到原始组件告诉它实际操作(复制或移动),这听起来过于复杂。
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.TransferHandler;
import javax.swing.table.DefaultTableModel;
public class DropExample extends JPanel {
public static void main(final String[] args) {
final JFrame frame = new JFrame();
frame.setSize(200, 100);
frame.add(new DropExample());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public DropExample() {
add(createTable());
final JButton button = new JButton("Drop here");
button.setDropTarget(new DropTarget(button, new DropTargetAdapter() {
@Override
public void drop(final DropTargetDropEvent dtde) {
//Here we accept the drop, as COPY:
dtde.acceptDrop(DnDConstants.ACTION_COPY);
dtde.dropComplete(true);
}
}));
add(button);
}
private JTable createTable() {
final DefaultTableModel tm = new DefaultTableModel();
tm.addColumn("Column 0");
tm.addRow(new String[] { "Table 00" });
final JTable table = new JTable(tm);
table.setDragEnabled(true);
table.setTransferHandler(new TransferHandler() {
private static final long serialVersionUID = 1L;
@Override
public int getSourceActions(final JComponent c) {
return COPY_OR_MOVE;
}
@Override
protected Transferable createTransferable(final JComponent c) {
return new StringSelection(c.toString());
}
@Override
protected void exportDone(final JComponent source, final Transferable data, final int action) {
System.out.println(((action & DnDConstants.ACTION_MOVE) > 0)?"is move":"not move");
System.out.println(((action & DnDConstants.ACTION_COPY) > 0)?"is copy":"not copy");
// On Java 7 it reports: "is move" and "not copy"
// On Java 6 it (correctly) reports: "not move" and "is copy"
}
});
return table;
}
}