【问题标题】:Drag and Drop of JPanel wont dropJPanel 的拖放不会掉落
【发布时间】:2012-10-11 10:46:41
【问题描述】:

我基本上是在尝试拖放一个包含 Jlabel 的 JPanel:

这是我实现的拖放代码示例:

public class TestDragAndDropPanel extends JPanel{

private static final long serialVersionUID = 1L;
Border borderContainer = BorderFactory.createMatteBorder(2, 2, 2, 2, Color.BLACK);
private DataFlavor dataFlavor = new DataFlavor(TestDragAndDropPanel.class, "TestDragAndDropPanel");


public TestDragAndDropPanel(){
            JPanel mainDragPanel = new JPanel();
    mainDragPanel.setBorder(borderContainer);

    JPanel mainDropPanel = new JPanel();
    mainDropPanel.setBorder(borderContainer);

    JPanel draggablePanel = new JPanel();
    draggablePanel.setBorder(borderContainer);
    JLabel draggableTitle = new JLabel("This is Draggable");
    JLabel draggableTitle2 = new JLabel("Another Component");
    draggablePanel.add(draggableTitle);
    draggablePanel.add(draggableTitle2);

    JPanel droppablePanel = new JPanel();
    droppablePanel.setBorder(borderContainer);
    JLabel droppableTitle = new JLabel("This is Droppable");
    JLabel droppableTitle2 = new JLabel("Another Component 2");
    droppablePanel.add(droppableTitle);
    droppablePanel.add(droppableTitle2);

    mainDragPanel.add(draggablePanel);
    mainDropPanel.add(droppablePanel);
    this.add(mainDragPanel);
    this.add(mainDropPanel);

    init(mainDropPanel, draggablePanel);
}

private void init(JPanel mainDropPanel, JPanel draggablePanel) {
    DragSource ds = new DragSource();
    ds.createDefaultDragGestureRecognizer(draggablePanel, DnDConstants.ACTION_MOVE, new DragGestureListImp());

    new MyDropTargetListImp(mainDropPanel);
}

private class TransferablePanel implements Transferable { 

    private JPanel transferablePanel;

    public TransferablePanel(JPanel transferablePanel) {
        this.transferablePanel = transferablePanel;
    } 

    @Override
    public DataFlavor[] getTransferDataFlavors() {
        return new DataFlavor[] { dataFlavor };
    }

    @Override
    public boolean isDataFlavorSupported(DataFlavor flavor) {
        return flavor.equals(dataFlavor);
    }

    @Override
    public Object getTransferData(DataFlavor flavor)
        throws UnsupportedFlavorException, IOException {

        if (flavor.equals(dataFlavor)){
            return transferablePanel;
        } else {
            throw new UnsupportedFlavorException(flavor);
        }
    }
}

private class DragGestureListImp implements DragGestureListener {

    @Override
    public void dragGestureRecognized(DragGestureEvent event) {
        Cursor cursor = null;
        JPanel panel = (JPanel) event.getComponent();

        if (event.getDragAction() == DnDConstants.ACTION_MOVE) {
            cursor = DragSource.DefaultMoveDrop;
        }
        event.startDrag(cursor, new TransferablePanel(panel));
    }
}

private class MyDropTargetListImp extends DropTargetAdapter implements DropTargetListener {

    private DropTarget dropTarget;
    private JPanel panel;

    public MyDropTargetListImp(JPanel panel) {
        this.panel = panel;
        dropTarget = new DropTarget(panel, DnDConstants.ACTION_MOVE, this,
                true, null);
    }

    public void drop(DropTargetDropEvent event) {
        try {
            Transferable tr = event.getTransferable();
            JPanel an = (JPanel) tr.getTransferData(dataFlavor);

            if (event.isDataFlavorSupported(dataFlavor)) {
                event.acceptDrop(DnDConstants.ACTION_MOVE);
                this.panel.add(an);
                event.dropComplete(true);
                this.panel.validate();
                this.panel.repaint();
                return;
            }
            event.rejectDrop();
        } catch (Exception e) {
            e.printStackTrace();
            event.rejectDrop();
        }
    }
}

public static void main(String[] args){
    System.out.println("Application Running");
    JPanel testDragAndDropPanel =  new TestDragAndDropPanel();

    JFrame mainframe =  new JFrame();
    mainframe.add(testDragAndDropPanel);
    mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    mainframe.setSize(300,200);
    mainframe.setVisible(true);
}
}

基本上,drop 方面似乎没有发生任何事情,谁能告诉我为什么?

谢谢,

【问题讨论】:

    标签: java swing drag-and-drop awt jpanel


    【解决方案1】:

    你确定什么都没有发生吗?如果您在放下面板后最大化您的窗口,那么您会看到更改。问题是您没有重新验证下拉面板。

    在您的drop 方法中,替换这部分

    if (event.isDataFlavorSupported(dataFlavor)) {
        event.acceptDrop(DnDConstants.ACTION_MOVE);
        this.panel.add(an);
        event.dropComplete(true);
        this.panel.validate();
        this.panel.repaint();
        return;
    }
    

    有了这个

    if (event.isDataFlavorSupported(dataFlavor)) {
        event.acceptDrop(DnDConstants.ACTION_MOVE);
        panel.add(an);
        panel.revalidate();
        event.dropComplete(true);
        return;
    }
    

    【讨论】:

    • 啊,好一个 - 为什么验证不适用于这个呢?你什么时候会使用验证?
    • 在 Swing 应用程序中,您应该在大多数情况下使用 revalidate(有时可能后面跟着 repaint,视情况而定,您应该尝试一下)
    猜你喜欢
    • 2012-07-19
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多