从 JTable 拖放到 JLayeredPane

Drag and Drop from JTable to JLayeredPane

如何创建 在 JTableJLayeredPane 之间拖放。

有人知道如何实现吗?

我需要通过在 JTable 和 JLayeredPane 之间拖放来传输对象

DropTarget dt = new DropTarget(Droptargetobject, new DropTargetAdapter() {

        @Override
        public void dragEnter(DropTargetDragEvent dtde) {
            //executed if mouse with items enters object
        }

        @Override
        public void drop(DropTargetDropEvent dtde) {
            //executed if you drop the item
        }
});

并使用 java.awt.dnd.DragGestureEvent; 实现拖动。 我希望你明白我的意思

我使用的导入:

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;

你至少需要做一些事情才能让它工作:

  • 在您的 JTable 实例上调用 setDragEnabled(true)
  • 设置 JTables 和 JLayeredPanes DropTarget
  • 创建一个可拖动的 Component 以添加到 JLayeredPane

要设置 Components DropTarget,请调用 setDropTarget(DropTarget d) 方法并传递匿名内部 class 作为参数。将 Transferables 数据放入 Component 的代码应位于 drop(DropTargetDropEvent dtde) 方法中。

下面的代码片段展示了如何接收 Transferable 并将其插入到 JTable 开始放置的行中:

table.setDropTarget(new DropTarget() {

    @Override
    public synchronized void drop(DropTargetDropEvent dtde) {
        try {
            // get row to put new item in
            int row = table.rowAtPoint(dtde.getLocation());
            // inserting row:
            ((DefaultTableModel) table.getModel()).insertRow(
                    //if the row wasn't found, add it to the end of the JTable
                    row == -1 ? table.getRowCount() : row,
                    // pass string flavor of transferable data as row data parameter
                    new Object[] {dtde.getTransferable()
                                .getTransferData(DataFlavor.stringFlavor)});
        } catch(UnsupportedFlavorException | IOException e) {
            e.printStackTrace();
        }
    }
});

下面的代码片段再次收到 Transferable,但将其添加到 JLayeredPane 的末尾。请注意,组件被添加到 JLayeredPane 的末尾,因为我为其分配了一个 BoxLayout(SwingConstants.VERTICAL)

layeredPane.setDropTarget(new DropTarget() {

    @Override
    public synchronized void drop(DropTargetDropEvent dtde) {
        try {
            // create draggable label to add to layered pane 
            // creating this class will be explained next
            final DraggableLabel label = new DraggableLabel(
                    (String) dtde.getTransferable()
                    .getTransferData(DataFlavor.stringFlavor));

            // add label to layered pane
            layeredPane.add(label, JLayeredPane.DEFAULT_LAYER);
            layeredPane.revalidate();
            layeredPane.repaint();
        } catch(UnsupportedFlavorException | IOException e) {
            e.printStackTrace();
        }
    }

});

要创建可拖动的 Component(在此示例中为 JLabel),您必须:

  • 创建一个新的 class extends JLabelimplements DragGestureListener and DragSourceListener
  • 覆盖所有必要的方法
  • 在构造函数中:
  • 使用 dragGestureRecognized(DragGestureEvent evt) 方法中的 DragSource 开始拖动

class DraggableLabel extends JLabel implements DragGestureListener, DragSourceListener {

    private DragSource dragSource;

    DraggableLabel(String text) {
        super(text);

        // create the drag source
        dragSource = new DragSource();
        // assign this component a DragGestureRecognizer
        dragSource.createDefaultDragGestureRecognizer(
                this, DnDConstants.ACTION_COPY_OR_MOVE, this);

        // for contrast with other items in layered pane
        setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
    }

    @Override
    public void dragGestureRecognized(DragGestureEvent evt) {
        dragSource.startDrag(
                evt, //trigger event
                DragSource.DefaultMoveDrop, // icon
                new StringSelection(getText()), // transferable data
                this); // this the DragSourceListener
    }

    @Override
    public void dragEnter(DragSourceDragEvent evt) {}

    @Override
    public void dragOver(DragSourceDragEvent evt) {}

    @Override
    public void dragExit(DragSourceEvent evt) {}

    @Override
    public void dropActionChanged(DragSourceDragEvent evt) {}

    @Override
    public void dragDropEnd(DragSourceDropEvent evt) {}

}

完整的工作示例:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDropEvent;
import java.io.IOException;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JTable;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableModel;

class DragDropExample {

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            final JFrame frame = new JFrame("JLabel Text Example");

            final JTable table = new JTable(new DefaultTableModel(
                    new Object[][] {
                            {"Item 1"},
                            {"Item 2"},
                            {"Item 3"},
                            {"Item 4"},
                            {"Item 5"}},
                    new String[] {"Column Name"}));
            table.setDragEnabled(true);
            table.setDropTarget(new DropTarget() {

                @Override
                public synchronized void drop(DropTargetDropEvent dtde) {
                    try {
                        // get row to put new item in
                        int row = table.rowAtPoint(dtde.getLocation());
                        // inserting row:
                        ((DefaultTableModel) table.getModel()).insertRow(
                                //if the row wasn't found, add it to the end of the JTable
                                row == -1 ? table.getRowCount() : row,
                                // pass string flavor of transferable data as row data parameter
                                new Object[] {dtde.getTransferable()
                                        .getTransferData(DataFlavor.stringFlavor)});
                    } catch(UnsupportedFlavorException | IOException e) {
                        e.printStackTrace();
                    }
                }
            });

            final JLayeredPane layeredPane = new JLayeredPane() {

                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(200, 300);
                }

            };
            layeredPane.setBorder(BorderFactory.createLineBorder(Color.BLACK));
            layeredPane.setLayout(new BoxLayout(layeredPane, BoxLayout.Y_AXIS));
            layeredPane.setDropTarget(new DropTarget() {

                @Override
                public synchronized void drop(DropTargetDropEvent dtde) {
                    try {
                        // create draggable label to add to layered pane
                        // creating this class will be explained next
                        final DraggableLabel label = new DraggableLabel(
                                (String) dtde.getTransferable()
                                        .getTransferData(DataFlavor.stringFlavor));

                        // add label to layered pane
                        layeredPane.add(label, JLayeredPane.DEFAULT_LAYER);
                        layeredPane.revalidate();
                        layeredPane.repaint();
                    } catch(UnsupportedFlavorException | IOException e) {
                        e.printStackTrace();
                    }
                }

            });

            frame.getContentPane().add(table, BorderLayout.WEST);
            frame.getContentPane().add(layeredPane);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }

    static class DraggableLabel extends JLabel implements DragGestureListener, DragSourceListener {

        private DragSource dragSource;

        DraggableLabel(String text) {
            super(text);

            // create the drag source
            dragSource = new DragSource();
            // assign this component a DragGestureRecognizer
            dragSource.createDefaultDragGestureRecognizer(
                    this, DnDConstants.ACTION_COPY_OR_MOVE, this);

            // for contrast with other items
            setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
        }

        @Override
        public void dragGestureRecognized(DragGestureEvent evt) {
            dragSource.startDrag(
                    evt, //trigger event
                    DragSource.DefaultMoveDrop,
                    new StringSelection(getText()),
                    this);
        }

        @Override
        public void dragEnter(DragSourceDragEvent evt) {}

        @Override
        public void dragOver(DragSourceDragEvent evt) {}

        @Override
        public void dragExit(DragSourceEvent evt) {}

        @Override
        public void dropActionChanged(DragSourceDragEvent evt) {}

        @Override
        public void dragDropEnd(DragSourceDropEvent evt) {}

    }

}