DropDemo 中的 ListTransferHandler 有一个 bug

发布于 2024-10-20 08:56:23 字数 1053 浏览 3 评论 0原文

这是从 OTN 讨论论坛 转发的,因为我在那里没有得到答案。

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

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

而不是:

  • List Item 1
  • List Item 0

我得到这个:

  • List Item 1
  • List Item 1

这显然不是预期的结果。

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

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

有人可以为我提供一个可用的 ListTransferHandler 或者知道如何修复演示中使用的 ListTransferHandler 吗?

谢谢并致以最诚挚的问候, 库尔特

this is a repost from the OTN Discussions Forum because I did not get an answer there.

In Java, I would like to enable Drag and Drop in a JList containing Strings. To do that, I used the ListTransferHandler.java that is used in Oracle's DropDemo. Unfortunately, this ListTransferHandler.java has a bug.

To reproduce the error in the ListTransferHandler.java I did the following:

Instead of this:

  • List Item 1
  • List Item 0

I get this:

  • List Item 1
  • List Item 1

which is obviously not the expected result.

Netbeans' output window did not show any error messages. I tried to find the bug myself, but was not successful.

So am I missing the point of enabling DnD in a JList? Don't I need to implement a ListTransferHandler myself?

Has anybody a working ListTransferHandler for me please or know how to fix the one used in the demo?

Thanks and best regards,
Kurt

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

疾风者 2024-10-27 08:56:23

这绝对是一个错误。看一下 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;
        //.....

}

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

That is definitely a bug. Take a look at the ListTransferHandler#cleanup method. Its goal is to delete previously selected item from the list. Indexes correction is performed before deletion:

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

Somehow, method ListTransferHandler#importString that initializes addCount is never called, hence, correction is never done.

As a workaround, you can initialize it yourself:

        int addCount = indices.length;

That will fix INSERT drop mode.

UPD:

Just noticed that other drop modes are broken too. So, the final fix (seems to be it):

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;
        //.....

}

Also, all unused fields and methods should be removed.

影子是时光的心 2024-10-27 08:56:23

@n0weak 感谢您的回答,我可以根据我的需要修复 ListTransferHandler (多个选择仍然被破坏,并且我没有测试除 INSERT 之外的其他模式)。

我发现除了上面的解决方案之外,还有必要记住 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 */

@n0weak thanks to your answer I could fix the ListTransferHandler for my needs (multiple selections are still broken, and I haven't tested other modes than INSERT).

I found it necessary to remember the addIndex in addition to your solution above. Here are the code changes I used:

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 */
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文