Java DropDemo中的ListTransferHandler有一个bug

Java DropDemo中的ListTransferHandler有一个bug,java,drag-and-drop,jlist,Java,Drag And Drop,Jlist,这是一个来自的转载,因为我没有得到一个答案 在Java中,我希望在包含字符串的JList中启用拖放。为此,我使用了Oracle DropDemo中使用的ListTransferHandler.java。不幸的是,这个ListTransferHandler.java有一个bug 要在ListTransferHandler.java中重现错误,我执行了以下操作: 从下载Drop演示项目 在Netbeans中运行它 将列表放置模式更改为插入 将列表项1拖放到列表项0上方 与此相反: 清单项目1

这是一个来自的转载,因为我没有得到一个答案

在Java中,我希望在包含字符串的JList中启用拖放。为此,我使用了Oracle DropDemo中使用的ListTransferHandler.java。不幸的是,这个ListTransferHandler.java有一个bug

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

  • 从下载Drop演示项目
  • 在Netbeans中运行它
  • 将列表放置模式更改为插入
  • 将列表项1拖放到列表项0上方
与此相反:

  • 清单项目1
  • 列表项0
我明白了:

  • 清单项目1
  • 清单项目1
这显然不是预期的结果

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

那么,我是否错过了在JList中启用DnD的要点?我不需要自己实现ListTransferHandler吗

有没有人能为我提供一个工作的ListTransferHandler,或者知道如何修复演示中使用的ListTransferHandler

谢谢并致以最良好的祝愿,
库尔特

那肯定是个bug。请看一下ListTransferHandler#cleanup方法。其目标是从列表中删除以前选择的项。删除前执行索引更正:

        if (addCount > 0) {
            for (int i = 0; i < indices.length; i++) {
                if (indices[i] > addIndex) {
                    indices[i] += addCount;
                }
            }
        }
这将修复插入-删除模式

UPD:

只是注意到其他下降模式也被破坏了。因此,最后的解决办法(似乎是):


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

@n0weak多亏了您的回答,我可以根据自己的需要修复ListTransferHandler(多个选择仍然被破坏,除了插入,我还没有测试其他模式)

我发现除了上面的解决方案之外,还需要记住
addIndex
。以下是我使用的代码更改:

public class ListTransferHandler extends TransferHandler {
    // ...
    private boolean insert;
    // ...

public boolean importData(TransferHandler.TransferSupport info) {
        // ...            
        // method local variables were mistakenly used
        insert = dl.isInsert();
        addIndex = dl.getIndex(); // also replace index with addIndex a few lines below
        addCount = indices.length;
        // ...

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

/* protected void importString(JComponent c, String str) {...} 
   This method is never called */

对于INSERT,bool remove应该是false,但它是true。@StackOverflowException只要
remove=(action==TransferHandler.MOVE)
仅当用户按住Ctrl键时才执行实际插入。
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;
        //.....

}
public class ListTransferHandler extends TransferHandler {
    // ...
    private boolean insert;
    // ...

public boolean importData(TransferHandler.TransferSupport info) {
        // ...            
        // method local variables were mistakenly used
        insert = dl.isInsert();
        addIndex = dl.getIndex(); // also replace index with addIndex a few lines below
        addCount = indices.length;
        // ...

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

/* protected void importString(JComponent c, String str) {...} 
   This method is never called */