The following demo, ChooseDropActionDemo
, contains three lists. As you can see in the screen shot, the list on the left, labeled "Drag from here", is the drag source. This list supports both move and copy but it does not implement import — so you cannot drop into it.
On the right side are two lists that act as drop targets. The top list, labeled "Drop to COPY here" will only allow data to be copied to it. The bottom list, labeled "Drop to MOVE here" will only allow data to be moved to it. The source list only allows data to be dragged from it.
ChooseDropActionDemo
using
Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.canImport
method for the transfer handler was coded to reject the COPY action, but it could have been implemented to return true, in which case the user action would prevail and a copy would occur.As you might guess, the
example contains two ChooseDropActionDemo.java
TransferHandler
implementations:
/** * The FromTransferHandler allows dragging from the list and * supports both copy and move actions. This transfer handler * does not support import. */ 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); } } /** * The ToTransferHandler has a constructor that specifies whether the * instance will support only the copy action or the move action. * This transfer handler does not support export. */ class ToTransferHandler extends TransferHandler { int action; public ToTransferHandler(int action) { this.action = action; } public boolean canImport(TransferHandler.TransferSupport support) { // for the demo, we will only support drops (not clipboard paste) if (!support.isDrop()) { return false; } // we only import Strings if (!support.isDataFlavorSupported(DataFlavor.stringFlavor)) { return false; } // check if the source actions contain the desired action - // either copy or move, depending on what was specified when // this instance was created boolean actionSupported = (action & support.getSourceDropActions()) == action; if (actionSupported) { support.setDropAction(action); return true; } // the desired action is not supported, so reject the transfer return false; } public boolean importData(TransferHandler.TransferSupport support) { // if we cannot handle the import, say so if (!canImport(support)) { return false; } // fetch the drop location JList.DropLocation dl = (JList.DropLocation)support.getDropLocation(); int index = dl.getIndex(); // fetch the data and bail if this fails 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; } }
The FromTransferHandler
, attached to the source list, allows for dragging from the list and supports both copy and move actions. If you try to drop onto this list, the drop will be rejected because FromTransferHandler
has not implemented the canImport
and importData
methods.
The ToTransferHandler
, attached to both the move-only and the copy-only target list, contains a constructor that specifies whether the target list will allow only copy or only move. An instance that supports the copy action is attached to the copy-only list and an instance that supports the move action is attached to the move-only list.
You might also be interested in the Top-Level Drop example which also illustrates choosing the drop action.
Next we look at showing the drop location.