我的应用程序包含一些由 DnD 移动的 JPanel。我已经实现了所有的侦听器和处理程序,一切似乎都是正确的。当用鼠标拖动一个面板时,我的 DragGestureListener 识别出这一点并想要开始一个新的 DragAction:
@Override
public void dragGestureRecognized(DragGestureEvent dge) {
// When the drag begins, we need to grab a reference to the
// parent container so we can return it if the drop
// is rejected
Container parent = getPanel().getParent();
setParent(parent);
// Remove the panel from the parent. If we don't do this, it
// can cause serialization issues. We could over come this
// by allowing the drop target to remove the component, but that's
// an argument for another day
parent.remove(getPanel());
// Update the display
parent.invalidate();
parent.repaint();
// Create our transferable wrapper
TicketTransferable transferable = new TicketTransferable(getPanel());
// Start the "drag" process...
dge.startDrag(null, transferable);
}
但随后发生以下异常:
exception in thread "AWT-EventQueue-0" java.awt.dnd.InvalidDnDOperationException:
Cannot find top-level for the drag source component
at sun.awt.X11.XDragSourceContextPeer.startDrag(XDragSourceContextPeer.java:126)
at sun.awt.dnd.SunDragSourceContextPeer.startDrag(SunDragSourceContextPeer.java:134)
我检查了 XDragSourceContextPeer 并发现触发 DragAction 的组件(在我的情况下是 JPanel 自行移动)必须是“Window”类型才能正确启动拖动。关键是我的 JPanel 不是一个窗口,并且提到的异常被抛出。
我究竟做错了什么?
PS:所有“可移动”面板都位于 JTable 的不同单元格中。