自定义TransferHandler的D& D和CCP问题

时间:2014-07-05 21:11:31

标签: java swing drag-and-drop copy-paste

我无法为使用自定义TransferHandler的{​​{1}}实施自定义JTree。 问题来自我用来管理数据的具体TreeModel

据我所知,在摇摆拖拉中Drop的工作原理如下:

  1. 用户开始拖动,数据通过传输处理程序从模型中获取
  2. 用户删除容器上的数据
  3. 在传输处理程序上调用importData(数据应添加到此处的模型中)
  4. 在传输处理程序上调用exportDone(此处应从模型中删除数据)
  5. 对我来说这是一个很大的问题,因为我的模型不能包含任何数据两次。我需要的是:

    1. 从旧位置移除模型中的数据
    2. 将数据添加到新位置的模型
    3. 我用谷歌搜索了这个,我发现的唯一的东西是一个小黑客,基本上滥用importData方法也先删除数据而忽略了exportDone方法。

      这适用于Drag&掉线,但它打破了CCP的功能。 中共被打破了,因为在TreeModel方法中,我无法确定出口是否是拖拽和放大器。掉落或者如果是切割。我需要从模型中删除数据,如果它是一个剪切,但不是如果它是一个下降。

      此外,对于使用复制和剪切的exportDone方法,我还有另一个问题。如果是副本我需要克隆我的数据,但是当它是一个剪切我不需要克隆,我实际上更愿意,如果我没有这样做以保留旧的引用。 但是importData方法中给出的唯一参数是importData对象。 TransferSupport无法告诉您该操作是复制还是剪切操作。

      以下是代码,如果有任何帮助:(已经很大,抱歉)

      TransferSupport

      阻力& drop工作,但由于缺少信息,Copy-Cut-Paste不能正常工作......

1 个答案:

答案 0 :(得分:1)

在此之前,我假设您知道在importData之后调用exportDone进行拖放,并在importData之前调用ccp(剪切副本)
另外我假设你知道拖动会调用剪切动作而ctrl + drag会调用复制动作。
因此,为了知道操作是dnd还是ccp,你必须在importData上设置一个标志 在这里,我使用了isDrag标志来设置..

public class JTreeTransferHandler extends TransferHandler {

private final DataFlavor nodeFlavor;

Boolean isCut;
Boolean isdrag = false;

@Override
public int getSourceActions(JComponent c) {
    return COPY_OR_MOVE;
}

@Override
protected Transferable createTransferable(JComponent source) {

}

@Override
protected void exportDone(JComponent source, Transferable data, int action) {
    isCut = action == MOVE; //to check whether the operation is cut or copy
    if (isdrag) {
        if (isCut) {
            //Implement you drag code (normal drag)
        } else {
            //Implement you ctrl+drag code
        }
    }
    isdrag = false; //resetting the dnd flag
}

@Override
public boolean canImport(TransferHandler.TransferSupport support) {
    if (!support.isDataFlavorSupported(DataFlavors.nodeFlavor)) {
        return false;
    }
    if (support.isDrop()) {
        return canImportDnd();
    } else {
        return canImportccp();
    }
    return false;
}

@Override
public boolean importData(TransferHandler.TransferSupport support) {
    if (!canImport(support)) {
        return false;
    }
    if (support.isDrop()) {
        isdrag = true;//To know whether it is a drag and drop in exportdone
        if (support.getDropAction() == MOVE) {
            //Implement you drag code (normal drag)
        } else if (support.getDropAction() == COPY) {
            //Implement you ctrl+drag code
        }
    } else if (isCut) {
        //Implement you cut ctrl+x code
    }

    return true;
}

}