这是OTN Discussions Forum的转贴,因为我在那里没有得到答案。

在Java中,我想在包含字符串的JList中启用拖放功能。为此,我使用了Oracle DropDemo中使用的ListTransferHandler.java。不幸的是,此ListTransferHandler.java有一个错误。

为了重现ListTransferHandler.java中的错误,我执行了以下操作:


http://download.oracle.com/javase/tutorial/uiswing/examples/zipfiles/dnd-DropDemoProject.zip下载Drop演示项目
在Netbeans中运行
将列表放置模式更改为INSERT
将列表项1拖放到列表项0上方


代替这个:


清单项目1
清单项目0


我得到这个:


清单项目1
清单项目1


这显然不是预期的结果。

Netbeans的输出窗口未显示任何错误消息。我试图自己找到该错误,但没有成功。

因此,我是否错过了在JList中启用DnD的意义?我不需要自己实现ListTransferHandler吗?

请问有人为我工作的ListTransferHandler或知道如何修复演示中使用的那个吗?

谢谢和最诚挚的问候,
库尔特

最佳答案

那绝对是一个错误。看一下ListTransferHandler#cleanup方法。其目标是从列表中删除先前选择的项目。在删除之前执行索引更正:

        if (addCount > 0) {
            for (int i = 0; i < indices.length; i++) {
                if (indices[i] > addIndex) {
                    indices[i] += addCount;
                }
            }
        }


以某种方式,永远不会调用初始化addCount的ListTransferHandler#importString方法,因此,永远不会进行校正。

解决方法是,您可以自己初始化:

        int addCount = indices.length;


这将修复INSERT放置模式。

UPD:

只是注意到其他放置模式也已损坏。因此,最后的修复(似乎就是这样):

public class ListTransferHandler extends TransferHandler {
    private boolean insert;
    //........
    public boolean importData(TransferHandler.TransferSupport info) {
        //......
        insert = dl.isInsert();
        //......

    protected void exportDone(JComponent c, Transferable data, int action) {
        cleanup(c, insert && action == TransferHandler.MOVE);
    }

    protected void cleanup(JComponent c, boolean remove) {
        if (remove && indices != null) {
            int addCount = indices.length;
        //.....

}


另外,所有未使用的字段和方法都应删除。

09-25 18:00