如何在 JTable JLayeredPane 之间创建拖放。

有谁有任何想法如何实现这一目标?

我需要通过在JTable和JLayeredPane 之间拖放来转移对象。

最佳答案

您至少要做一些事情才能使它起作用:

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


  • 要设置ComponentDropTarget,请调用setDropTarget(DropTarget d)方法并传递一个匿名内部类作为参数。将 Transferable 的数据放入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),您必须:
  • 创建一个新类,将extends JLabelimplements DragGestureListener DragSourceListener
  • 覆盖所有必需的方法
  • 在构造函数中:
  • 创建一个新的 DragSource
  • 创建一个 DragGestureRecognizer 并将其分配给this JLabel子类和this DragGestureListener
  • 使用DragSource方法
  • 中的dragGestureRecognized(DragGestureEvent evt)开始拖动

    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) {}
    
        }
    
    }
    

    关于java - 从JTable拖放到JLayeredPane,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40906950/

    10-10 03:03