拖放后移动组件

时间:2013-05-10 08:51:23

标签: java swing awt

我见过code of drag and drop

问题1:在删除图像后,如何在丢弃的面板内移动图像(使用鼠标指针)。 (图像的目的地,我想要在哪里释放鼠标。然后改变位置(使用鼠标会更好。或使用按钮 - 但使用鼠标更好)

问题2:如何在结束后更改位置?

p.s我想在这里将图像转换为组件。

首先我拖放组件。然后使用鼠标指针更改位置(移动它)。

这是代码:

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
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.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.IOException;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestDnD {

    public static void main(String[] args) {
        new TestDnD();
    }

    public TestDnD() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class TestPane extends JPanel {

        private JList list;

        public TestPane() {
            setLayout(new BorderLayout());
            list = new JList();
            DefaultListModel model = new DefaultListModel();
            model.addElement(new User("Shaun"));
            model.addElement(new User("Andy"));
            model.addElement(new User("Luke"));
            model.addElement(new User("Han"));
            model.addElement(new User("Liea"));
            model.addElement(new User("Yoda"));
            list.setModel(model);
            add(new JScrollPane(list), BorderLayout.WEST);

            DragGestureRecognizer dgr = DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(
                            list,
                            DnDConstants.ACTION_COPY_OR_MOVE,
                            new DragGestureHandler(list));

            JPanel panel = new JPanel(new GridBagLayout());
            add(panel);

            DropTarget dt = new DropTarget(
                            panel,
                            DnDConstants.ACTION_COPY_OR_MOVE,
                            new DropTargetHandler(panel),
                            true);



        }

    }

    public static class User {

        private String name;        

        public User(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        @Override
        public String toString() {
            return name;
        }

    }

    public static class UserTransferable implements Transferable {

        public static final DataFlavor USER_DATA_FLAVOR = new DataFlavor(User.class, "User");
        private User user;

        public UserTransferable(User user) {
            this.user = user;
        }

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

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

        @Override
        public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
            Object value = null;
            if (USER_DATA_FLAVOR.equals(flavor)) {
                value = user;
            } else {
                throw new UnsupportedFlavorException(flavor);
            }
            return value;
        }

    }

    protected class DragGestureHandler implements DragGestureListener {

        private JList list;

        public DragGestureHandler(JList list) {
            this.list = list;
        }

        @Override
        public void dragGestureRecognized(DragGestureEvent dge) {
            Object selectedValue = list.getSelectedValue();
            if (selectedValue instanceof User) {
                User user = (User) selectedValue;

                Transferable t = new UserTransferable(user);
                DragSource ds = dge.getDragSource();
                ds.startDrag(dge, null, t, new DragSourceHandler());
            }

        }

    }

    protected class DragSourceHandler implements DragSourceListener {

        public void dragEnter(DragSourceDragEvent dsde) {
        }

        public void dragOver(DragSourceDragEvent dsde) {
        }

        public void dropActionChanged(DragSourceDragEvent dsde) {
        }

        public void dragExit(DragSourceEvent dse) {
        }

        public void dragDropEnd(DragSourceDropEvent dsde) {

            System.out.println("Drag ended...");

        }

    }

    protected class DropTargetHandler implements DropTargetListener {

        private JPanel panel;

        public DropTargetHandler(JPanel panel) {
            this.panel = panel;
        }

        public void dragEnter(DropTargetDragEvent dtde) {
            if (dtde.getTransferable().isDataFlavorSupported(UserTransferable.USER_DATA_FLAVOR)) {
                System.out.println("Accept...");
                dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
            } else {
                System.out.println("Drag...");
                dtde.rejectDrag();
            }
        }

        public void dragOver(DropTargetDragEvent dtde) {
        }

        public void dropActionChanged(DropTargetDragEvent dtde) {
        }

        public void dragExit(DropTargetEvent dte) {
        }

        public void drop(DropTargetDropEvent dtde) {
            System.out.println("Dropped...");
            if (dtde.getTransferable().isDataFlavorSupported(UserTransferable.USER_DATA_FLAVOR)) {
                Transferable t = dtde.getTransferable();
                if (t.isDataFlavorSupported(UserTransferable.USER_DATA_FLAVOR)) {
                    try {
                        Object transferData = t.getTransferData(UserTransferable.USER_DATA_FLAVOR);
                        if (transferData instanceof User) {
                            User user = (User) transferData;
                            dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
                            panel.add(new JLabel(user.getName()));
                            panel.revalidate();
                            panel.repaint();
                        } else {
                            dtde.rejectDrop();
                        }
                    } catch (UnsupportedFlavorException ex) {
                        ex.printStackTrace();
                        dtde.rejectDrop();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                        dtde.rejectDrop();
                    }
                } else {
                    dtde.rejectDrop();
                }
            }
        }

    }

}

1 个答案:

答案 0 :(得分:3)

这是在两个相似窗格之间拖动图像的实现。

如果你要放弃Component s不允许移动的限制,你将会遇到困难,确保源和目标容器知道如何处理拖放(和渲染结果)

这花费了4个小时,所以在你敲定更新请求之前,请确保你已经努力理解代码并实现了自己的更改

实现将Image包装在DragImage类中,该类维护有关图像在其容器内的位置的信息,用于生成拖动图像......

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
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.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class TestDnD {

    public static void main(String[] args) {
        new TestDnD();
    }

    public TestDnD() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException ex) {
                    } catch (InstantiationException ex) {
                    } catch (IllegalAccessException ex) {
                    } catch (UnsupportedLookAndFeelException ex) {
                    }

                    JFrame frame = new JFrame("Test");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new GridLayout(0, 2, 10, 10));
                    ((JComponent) frame.getContentPane()).setBorder(new EmptyBorder(10, 10, 10, 10));

                    BufferedImage img = ImageIO.read(new File("issue376.jpg"));
                    ImagePane imagePane = new ImagePane();
                    imagePane.addImage(img);

                    frame.add(imagePane);
                    frame.add(new ImagePane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                    System.exit(0);
                }
            }

        });
    }

    public class ImagePane extends JPanel {

        private List<DragImage> images;
        private DragImages dropImages;
        private Point dragPoint;

        public ImagePane() {
            setBorder(new LineBorder(Color.GRAY));
            images = new ArrayList<>(25);

            DragGestureRecognizer dgr = DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(
                            this,
                            DnDConstants.ACTION_COPY_OR_MOVE,
                            new DragGestureHandler(this));

            DropTarget dt = new DropTarget(
                            this,
                            DnDConstants.ACTION_COPY_OR_MOVE,
                            new DropTargetHandler(this),
                            true);
        }

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

        public DragImage getImageAt(Point p) {
            DragImage at = null;
            for (DragImage di : images) {
                if (di.contains(p)) {
                    at = di;
                    break;
                }
            }
            return at;
        }

        protected boolean contains(Image image) {
            boolean contains = false;
            for (DragImage di : images) {
                if (di.getImage() == image) {
                    contains = true;
                    break;
                }
            }
            return contains;
        }

        public void addImage(Image image) {
            if (image != null) {
                if (!contains(image)) {
                    int x = (int) Math.round(Math.random() * getWidth());
                    int y = (int) Math.round(Math.random() * getHeight());
                    addImageAt(new Point(x, y), image);
                }
            }
        }

        public void addImageAt(Point p, Image image) {
            if (p != null && image != null) {
                if (!contains(image)) {
                    DragImage di = new DragImage(image, p);
                    images.add(di);
                    repaint();
                }
            }
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            for (DragImage di : images) {
                g2d.drawImage(di.getImage(), di.getLocation().x, di.getLocation().y, this);
            }
            if (dropImages != null) {
                g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
                Point offset = dropImages.getOffset();
                for (DragImage di : dropImages.getImages()) {
                    Point pp = new Point(dragPoint);
                    pp.x -= offset.getX();
                    pp.y -= offset.getY();
                    g2d.drawImage(di.getImage(), pp.x, pp.y, this);
                }
            }
            g2d.dispose();
        }

        public void removeImages(List list) {
            if (list != null && list.size() > 0) {
                for (Object obj : list) {
                    if (obj instanceof DragImage) {
                        removeImage((DragImage) obj);
                    }
                }
            }
        }

        public void removeImage(DragImage img) {
            images.remove(img);
            repaint();
        }

        protected void setDragImages(DragImages dragImages) {
            this.dropImages = dragImages;
            repaint();
        }

        public void addImagesAt(Point location, List images) {
            if (images != null && images.size() > 0) {
                for (Object obj : images) {
                    if (obj instanceof Image) {
                        Image img = (Image) obj;
                        addImageAt(location, img);
                        location.x += 10;
                        location.y += 10;
                        if (location.x >= getWidth()) {
                            location.x = 0;
                        }
                        if (location.y >= getHeight()) {
                            location.y = 0;
                        }
                    }
                }
            }
        }

        protected void addImages(DragImages dragImages) {
            for (DragImage di : dragImages.getImages()) {
                images.add(di);
            }
            repaint();
        }

        protected void addImagesAt(Point dropPoint, DragImages dragImages) {
            Point offset = dragImages.getOffset();
            for (DragImage di : dragImages.getImages()) {
                Point p = di.getLocation();
                p.x = dropPoint.x - offset.x;
                p.y = dropPoint.y - offset.y;
                images.add(di);
            }
            repaint();
        }

        protected void setDragPoint(Point location) {
            dragPoint = location;
            repaint();
        }

    }

    public static class ImageTransferable implements Transferable {

        public static final DataFlavor DRAG_IMAGE_DATA_FLAVOR = new DataFlavor(List.class, "Images");
        private DragImages dragImages;

        public ImageTransferable(DragImages dragImages) {
            this.dragImages = dragImages;
        }

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

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

        @Override
        public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
            return dragImages;
        }

    }

    public class DragImage {

        private Image image;
        private Point p;

        public DragImage(Image image, Point p) {
            this.image = image;
            this.p = p;
        }

        public Image getImage() {
            return image;
        }

        public Point getLocation() {
            return p;
        }

        public Dimension getSize() {
            return new Dimension(image.getWidth(null), image.getHeight(null));
        }

        public boolean contains(Point p) {
            return new Rectangle(getLocation(), getSize()).contains(p);
        }

    }

    public class DragImages {

        private Point offset;
        private List<DragImage> images;

        public DragImages(Point offset, DragImage... images) {
            this.offset = offset;
            this.images = Arrays.asList(images);
        }

        public Point getOffset() {
            return offset;
        }

        public List<DragImage> getImages() {
            return images;
        }

    }

    protected class DragGestureHandler implements DragGestureListener {

        private ImagePane imagePane;

        public DragGestureHandler(ImagePane list) {
            this.imagePane = list;
        }

        @Override
        public void dragGestureRecognized(DragGestureEvent dge) {
            DragImage di = imagePane.getImageAt(dge.getDragOrigin());
            if (di != null) {
                Point origin = dge.getDragOrigin();
                Point p = new Point();
                p.x = origin.x - di.getLocation().x;
                p.y = origin.y - di.getLocation().y;
                Transferable t = new ImageTransferable(new DragImages(p, di));
                imagePane.removeImage(di);
                DragSource ds = dge.getDragSource();
                ds.startDrag(
                                dge,
                                null,
                                t,
                                new DragSourceHandler(imagePane));
            }

        }

    }

    protected class DragSourceHandler implements DragSourceListener {

        private ImagePane pane;

        public DragSourceHandler(ImagePane pane) {
            this.pane = pane;
        }

        public void dragEnter(DragSourceDragEvent dsde) {
        }

        public void dragOver(DragSourceDragEvent dsde) {
            pane.repaint();
        }

        public void dropActionChanged(DragSourceDragEvent dsde) {
        }

        public void dragExit(DragSourceEvent dse) {
        }

        public void dragDropEnd(DragSourceDropEvent dsde) {
            if (!dsde.getDropSuccess()) {
                Transferable t = dsde.getDragSourceContext().getTransferable();
                if (t != null) {
                    try {
                        Object transferData = t.getTransferData(ImageTransferable.DRAG_IMAGE_DATA_FLAVOR);
                        if (transferData instanceof DragImages) {
                            DragImages di = (DragImages) transferData;
                            pane.addImages(di);
                        }
                    } catch (UnsupportedFlavorException | IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }

    }

    protected class DropTargetHandler implements DropTargetListener {

        private ImagePane panel;

        public DropTargetHandler(ImagePane panel) {
            this.panel = panel;
        }

        public void dragEnter(DropTargetDragEvent dtde) {
            if (dtde.getTransferable().isDataFlavorSupported(ImageTransferable.DRAG_IMAGE_DATA_FLAVOR)) {
                dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
                updateDragImages(dtde);
            } else {
                dtde.rejectDrag();
            }
        }

        public void dragOver(DropTargetDragEvent dtde) {
            updateDragImages(dtde);
            panel.repaint();
        }

        public void dropActionChanged(DropTargetDragEvent dtde) {
        }

        public void dragExit(DropTargetEvent dte) {
            panel.setDragImages(null);
        }

        public void drop(DropTargetDropEvent dtde) {
            panel.setDragImages(null);
            if (dtde.getTransferable().isDataFlavorSupported(ImageTransferable.DRAG_IMAGE_DATA_FLAVOR)) {
                Transferable t = dtde.getTransferable();
                if (t.isDataFlavorSupported(ImageTransferable.DRAG_IMAGE_DATA_FLAVOR)) {
                    try {
                        Object transferData = t.getTransferData(ImageTransferable.DRAG_IMAGE_DATA_FLAVOR);
                        if (transferData instanceof DragImages) {
                            DragImages images = (DragImages) transferData;
                            dtde.dropComplete(true);
                            dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
                            panel.addImagesAt(dtde.getLocation(), images);
                        } else {
                            dtde.rejectDrop();
                        }
                    } catch (UnsupportedFlavorException ex) {
                        ex.printStackTrace();
                        dtde.rejectDrop();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                        dtde.rejectDrop();
                    }
                } else {
                    dtde.rejectDrop();
                }
            }
        }

        protected void updateDragImages(DropTargetDragEvent dtde) {
            panel.setDragImages(null);
            Transferable t = dtde.getTransferable();
            if (t != null) {
                try {
                    Object transferData = t.getTransferData(ImageTransferable.DRAG_IMAGE_DATA_FLAVOR);
                    if (transferData instanceof DragImages) {
                        panel.setDragPoint(dtde.getLocation());
                        panel.setDragImages((DragImages)transferData);
                    }
                } catch (UnsupportedFlavorException | IOException ex) {
                    ex.printStackTrace();
                }
            }
        }

    }
}