Java教程是针对JDK 8编写的。本页中描述的示例和实践不利用后续版本中引入的改进,并且可能使用不再可用的技术。
有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言变化。
有关所有JDK版本的新功能、增强功能以及删除或弃用选项的信息,请参阅JDK发布说明。
以下演示,ChooseDropActionDemo,包含三个列表。如屏幕截图所示,左侧的列表标有“从这里拖动”,是拖动源。此列表支持移动和复制,但不支持导入,因此您无法将数据放置在其中。
右侧有两个作为放置目标的列表。顶部的列表标有“复制到这里”,只允许将数据复制到其中。底部的列表标有“移动到这里”,只允许将数据移动到其中。源列表只允许从中拖动数据。
ChooseDropActionDemo(下载JDK 7或更高版本)。或者,要自行编译和运行示例,请参阅示例索引。canImport方法被编码为拒绝复制操作,但它也可以实现返回true,这样用户操作将占优势,复制将发生。正如您可能猜到的,示例包含两个ChooseDropActionDemo.javaTransferHandler实现:
/**
* FromTransferHandler允许从列表中拖动,并支持复制和移动操作。此传输处理程序不支持导入。
*/
class FromTransferHandler extends TransferHandler {
public int getSourceActions(JComponent comp) {
return COPY_OR_MOVE;
}
private int index = 0;
public Transferable createTransferable(JComponent comp) {
index = dragFrom.getSelectedIndex();
if (index < 0 || index >= from.getSize()) {
return null;
}
return new StringSelection((String)dragFrom.getSelectedValue());
}
public void exportDone(JComponent comp, Transferable trans, int action) {
if (action != MOVE) {
return;
}
from.removeElementAt(index);
}
}
/**
* ToTransferHandler具有一个指定实例将仅支持复制操作还是移动操作的构造函数。此传输处理程序不支持导出。
*/
class ToTransferHandler extends TransferHandler {
int action;
public ToTransferHandler(int action) {
this.action = action;
}
public boolean canImport(TransferHandler.TransferSupport support) {
// 对于演示,我们只支持拖放(不支持剪贴板粘贴)
if (!support.isDrop()) {
return false;
}
// 我们只导入字符串
if (!support.isDataFlavorSupported(DataFlavor.stringFlavor)) {
return false;
}
// 检查源操作是否包含所需操作 - 复制或移动,具体取决于创建此实例时指定的内容
boolean actionSupported = (action & support.getSourceDropActions()) == action;
if (actionSupported) {
support.setDropAction(action);
return true;
}
// 不支持所需操作,因此拒绝传输
return false;
}
public boolean importData(TransferHandler.TransferSupport support) {
// 如果我们无法处理导入,请说明
if (!canImport(support)) {
return false;
}
// 获取放置位置
JList.DropLocation dl = (JList.DropLocation)support.getDropLocation();
int index = dl.getIndex();
// 获取数据并在失败时返回
String data;
try {
data = (String)support.getTransferable().getTransferData(DataFlavor.stringFlavor);
} catch (UnsupportedFlavorException e) {
return false;
} catch (java.io.IOException e) {
return false;
}
JList list = (JList)support.getComponent();
DefaultListModel model = (DefaultListModel)list.getModel();
model.insertElementAt(data, index);
Rectangle rect = list.getCellBounds(index, index);
list.scrollRectToVisible(rect);
list.setSelectedIndex(index);
list.requestFocusInWindow();
return true;
}
}
源列表上附加的FromTransferHandler允许从列表中拖拽,并支持复制和移动操作。如果您尝试将其拖放到该列表上,拖放操作将被拒绝,因为FromTransferHandler没有实现canImport和importData方法。
附加到仅支持移动和仅支持复制的目标列表的ToTransferHandler包含一个指定目标列表是否仅允许复制或仅允许移动的构造函数。一个支持复制操作的实例附加到仅支持复制的列表上,而一个支持移动操作的实例附加到仅支持移动的列表上。
您可能还对顶级拖放示例感兴趣,该示例还演示了如何选择拖放操作。
接下来,我们将看一下如何显示拖放位置。