Java中在JPanel中自定义拖放功能

9

Java自定义拖放 - 无需回调TransferHandler。

我想要为JPanel子类实现自定义拖放功能。我遵循了标准DnD教程的指导:

拖放和数据传输

表面上,事情似乎相当简单,但是当我实际尝试时,我没有看到任何DnD行为正在发生的迹象。事实上,我的TransferHandler中的任何方法都没有被调用。

因此,让我们回顾一下我做了什么...

我创建了自己的容器类,它声明自己扩展JPanel:

public class DnDUnitPanel extends JPanel
{
    ...
}

我从这个演示文稿中复制了ListTransferHandler: 拖放演示 将类重命名为DndUnitTransferHandler,删除了与JList对象相关的代码,并在其中每个方法上安装了System.out.println()语句。
然后我像这样实例化了两个不同的DnDUnitPanel实例:
DnDUnitPanel topPanel = new DnDUnitPanel(new GridLayout(0, 4, 6, 6), true);
// topPanel.setDragEnabled(true);
topPanel.setName("Top Panel");
topPanel.setTransferHandler(new DnDUnitTransferHandler());

DnDUnitPanel bottomPanel = new DnDUnitPanel(new GridLayout(0, 4, 6, 6), true);
// bottomPanel.setDragEnabled(true);
bottomPanel.setName("Bottom Panel");
bottomPanel.setTransferHandler(new DnDUnitTransferHandler());

(我还创建了一些JLabel实例并将它们add()到面板上(未显示)。)

当我尝试从一个面板拖动JLabel到另一个面板时,什么也没发生。因此,我回头重新阅读了这个页面:

传输处理器

特别是关于setDragEnabled()的内容:

turns on drag support. (The default is false.) This method is
defined on each component that supports the drag gesture; the link
takes you to the documentation for JList.

JPanel没有setDragEnabled()方法。那么,我就自己问了一下,“支持拖动手势的组件”到底是什么意思?
我最初认为这必须是声明实现MouseListener和/或MouseMotionListener的组件。我修改了DnDUnitPanel,声明它实现了这两个接口并提供了所有方法。这样做后,我可以看到mousePressed()、mouseClicked()、mouseDragged()等方法被调用了,但是TransferHandler仍然没有被调用,也没有拖动光标指示正在拖动或准备放置的内容。
然后,我查看了JList本身的源代码,并决定“支持拖动手势”实际上只是指具有关联的getter和setter的'dragEnabled'属性的内容。
因此,我通过直接从JList本身复制代码来声明该属性并提供getter和setter,将其应用于DnDUnitPanel(认为可能是我不完全理解的某些内容在调用isDragEnabled()并寻找true值以启动DnD行为)。
不幸的是,提供这些内容(并取消以上对DnDUnitPanel.setDragEnabled()的调用的注释)也没有效果。
因此...... TransferHandler从未被调用。显然,这里缺少重要的内容,但我看不出来缺少了什么。
我已经走投无路,不知道接下来该尝试什么。有人看出这里缺少了什么吗?
1个回答

11

1
我认为新手在使用DnD技术时最容易遇到的问题是没有意识到必须提供自己的MouseListener或MouseMotionListener才能启动拖动(对于不本身提供支持的自定义组件)。我发现dreamincode示例是最有用的。感谢@Xeon的回答。 - user1441004

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接