简体   繁体   English

从JTable拖放到JLayeredPane

[英]Drag and Drop from JTable to JLayeredPane

How to create Drag and drop between JTable and JLayeredPane . 如何在JTableJLayeredPane之间创建拖放。

Does anyone have any ideas how to implement this? 有没有人有任何想法如何实现这个?

I need transfer object by Drag and drop between JTable and JLayeredPane . 我需要在JTable和JLayeredPane之间拖放来传输对象

You have to do a few things at minimum to get this to work: 你必须至少做一些事情来实现这个目的:

  • Call setDragEnabled(true) on your JTable instance JTable实例上调用setDragEnabled(true)
  • Set the JTable s and JLayeredPane s DropTarget 设置JTableJLayeredPaneDropTarget
  • Create a draggable Component to add to the JLayeredPane 创建一个可拖动的Component以添加到JLayeredPane

To set a Component s DropTarget , call the setDropTarget(DropTarget d) method and pass an anonymous inner class as the argument. 要设置ComponentDropTarget ,请调用setDropTarget(DropTarget d)方法并传递匿名内部类作为参数。 Code that drops the Transferable s data into the Component should be located in the drop(DropTargetDropEvent dtde) method. Transferable s数据丢弃到Component应该位于drop(DropTargetDropEvent dtde)方法中。

The below snippet shows how to receive a Transferable and insert it into the row of a JTable where the drop was initiated: 下面的代码段显示了如何接收Transferable并将其插入到启动了drop的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();
        }
    }
});

This below snippet again receives a Transferable but instead adds it to the end of a JLayeredPane . 下面的代码片段再次收到Transferable但将其添加到JLayeredPane的末尾。 Note that components are added to the end of the JLayeredPane because I assign a BoxLayout(SwingConstants.VERTICAL) to it. 请注意,组件被添加到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();
        }
    }

});

To create a draggable Component (In this example a JLabel ), you must: 要创建可拖动的Component (在此示例中为JLabel ),您必须:

  • Create a new class that extends JLabel and implements DragGestureListener and DragSourceListener 创建一个extends JLabelimplements DragGestureListenerDragSourceListener的新类
  • Override all the necessary methods 覆盖所有必要的方法
  • In the constructor: 在构造函数中:
  • Start a drag using the DragSource in the dragGestureRecognized(DragGestureEvent evt) method 使用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) {}

}

Full working example: 完整的工作示例:

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

    }

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

and to implement the drag use a java.awt.dnd.DragGestureEvent; 并实现拖动使用java.awt.dnd.DragGestureEvent; . i hope you understand what i mean 我希望你明白我的意思

imports i used: 我使用的进口:

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM