演示-ChooseDropAction

以下演示ChooseDropActionDemo包含三个列表。从屏幕快照中可以看到,左侧的列表标记为“从此处拖动”是拖动源。该列表同时支持移动和复制,但不支持导入-因此您无法加入列表。

右侧是两个充当放置目标的列表。顶部的标签为“在此处拖放到 COPY”将仅允许将数据复制到其中。底部列表标记为“在此处拖放到移动”将仅允许将数据移动到该列表。源列表仅允许从中拖动数据。

ChooseDropActionDemo 演示的快照。

Try this:

  • 单击启动按钮以使用Java™Web 开始(下载 JDK 7 或更高版本)运行ChooseDropActionDemo。另外,要自己编译和运行示例,请查阅example index

  • 在源列表中选择一个项目,然后拖动到上层目标列表。当您在目标上拖动时,请注意,即使没有按住 Control 键表示要执行复制操作,也将显示复制鼠标光标。 (请注意,除非您按 Option 键,否则复制光标不会出现在 Macintosh 平台上.)

  • 放下该物品。根据需要,它已插入目标列表,但未从源中删除。

  • 再次从源列表中拖动,但是这次拖动到较低的目标列表中。放下该物品。它被插入到目标列表中,并从源列表中删除。

  • 在源列表中选择另一个项目,然后按 Control 键指示对 COPY 操作的首选项,将项目拖到较低的目标列表中。

  • 将项目放入列表。该项目未插入-丢弃被拒绝。传输处理程序的canImport方法已被编码为拒绝 COPY 操作,但可以实现为返回 true,在这种情况下,将以用户操作为准,并且将发生复制。

您可能会猜到,ChooseDropActionDemo.java示例包含两个TransferHandler实现:

/**
 * 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;
    }  
}

附加到源列表的FromTransferHandler允许从列表中拖动,并支持复制和移动动作。如果try放入此列表,则由于FromTransferHandler尚未实现canImportimportData方法而将拒绝该删除。

“仅移动”和“仅复制”目标列表都附有的ToTransferHandler包含一个构造函数,用于指定目标列表将只允许复制还是仅允许移动。支持复制操作的实例附加到仅复制列表,而支持移动操作的实例附加到仅移动列表。

您可能还对Top-Level Drop示例感兴趣,该示例还说明了选择放置动作。

接下来,我们看一下放置位置。