Drag and Drop from JTable to JLayeredPane

倾然丶 夕夏残阳落幕 提交于 2019-12-10 18:06:57

问题


How to create Drag and drop between JTable and JLayeredPane.

Does anyone have any ideas how to implement this?

I need transfer object by Drag and drop between JTable and JLayeredPane.


回答1:


You have to do a few things at minimum to get this to work:

  • Call setDragEnabled(true) on your JTable instance
  • Set the JTables and JLayeredPanes DropTarget
  • Create a draggable Component to add to the JLayeredPane

To set a Components DropTarget, call the setDropTarget(DropTarget d) method and pass an anonymous inner class as the argument. Code that drops the Transferables data into the Component should be located in the drop(DropTargetDropEvent dtde) method.

The below snippet shows how to receive a Transferable and insert it into the row of a JTable where the drop was initiated:

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. Note that components are added to the end of the JLayeredPane because I assign a BoxLayout(SwingConstants.VERTICAL) to it.

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:

  • Create a new class that extends JLabel and implements DragGestureListener and DragSourceListener
  • Override all the necessary methods
  • In the constructor:
    • Create a new DragSource
    • Create a DragGestureRecognizer and assign it to this the JLabel subclass and this the DragGestureListener
  • Start a drag using the DragSource in the dragGestureRecognized(DragGestureEvent evt) method

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

    }

}



回答2:


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;. 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;


来源:https://stackoverflow.com/questions/40906950/drag-and-drop-from-jtable-to-jlayeredpane

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!