Java 图像图标单击并在窗口周围拖动

Java 图像图标单击并在窗口周围拖动,java,drag-and-drop,draggable,imageicon,Java,Drag And Drop,Draggable,Imageicon,我试着在窗口周围点击并拖动一个图像图标(在本例中是一个卡片图像,但我想学习如何做),但我真的不知道怎么做。我想能够点击并按住鼠标按钮,拖动图像图标,并在我释放鼠标按钮时停留在原地 这是我目前掌握的代码: import javax.swing.*; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener;

我试着在窗口周围点击并拖动一个图像图标(在本例中是一个卡片图像,但我想学习如何做),但我真的不知道怎么做。我想能够点击并按住鼠标按钮,拖动图像图标,并在我释放鼠标按钮时停留在原地

这是我目前掌握的代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class MyFirstClass 
{

    public static void main(String[] args)
    {
        //load the card image from the gif file.
        final ImageIcon cardIcon = new ImageIcon("cardImages/tenClubs.gif");
        JLabel lbl = new JLabel(cardIcon);
        //create a panel displaying the card image
        JPanel panel = new JPanel()
        {
            //paintComponent is called automatically by the JRE whenever
            //the panel needs to be drawn or redrawn
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                cardIcon.paintIcon(this, g, 20, 20);
            }
        };

        lbl.setTransferHandler(null);
        MouseListener listener = new MouseAdapter() {
          public void mousePressed(MouseEvent me) {
            JComponent comp = (JComponent) me.getSource();
            TransferHandler handler = comp.getTransferHandler();
            handler.exportAsDrag(comp, me, TransferHandler.COPY);
          }
        };
        lbl.addMouseListener(listener);

        //create & make visible a JFrame to contain the panel
        JFrame window = new JFrame("Cards");
        window.add(panel);
        window.setPreferredSize(new Dimension(200,200));
        window.pack();
        window.setVisible(true);
    }
}

谢谢。

问题是您在混合范例…更不用说您似乎从未向任何内容添加
lbl
,因此它永远不可能接收事件,而且
面板在布局管理器的控制下,这使得移动组件非常困难

在Swing中,至少有三种不同的拖动方式,您使用的方式取决于您想要实现的目标

你可以…

使用
MouseListener
MouseMotationListener
手动执行操作。如果您想将对象物理地放置在容器中的某个位置,例如,您正在尝试这样做,这将非常有用

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class DragMe {

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

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

                JFrame frame = new JFrame("Testing");
                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 BufferedImage img;
        private Point imgPoint = new Point(0, 0);

        public TestPane() {
            try {
                img = ImageIO.read(new File("Computer.png"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            MouseAdapter ma = new MouseAdapter() {

                private Point offset;

                @Override
                public void mousePressed(MouseEvent e) {
                    Rectangle bounds = getImageBounds();
                    Point mp = e.getPoint();
                    if (bounds.contains(mp)) {
                        offset = new Point();
                        offset.x = mp.x - bounds.x;
                        offset.y = mp.y - bounds.y;
                    }
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    offset = null;
                }

                @Override
                public void mouseDragged(MouseEvent e) {
                    if (offset != null) {
                        Point mp = e.getPoint();
                        imgPoint.x = mp.x - offset.x;
                        imgPoint.y = mp.y - offset.y;
                        repaint();
                    }
                }

            };
            addMouseListener(ma);
            addMouseMotionListener(ma);
        }

        protected Rectangle getImageBounds() {
            Rectangle bounds = new Rectangle(0, 0, 0, 0);
            if (img != null) {
                bounds.setLocation(imgPoint);
                bounds.setSize(img.getWidth(), img.getHeight());
            }
            return bounds;
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (img != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.drawImage(img, imgPoint.x, imgPoint.y, this);
                g2d.dispose();
            }
        }
    }

}
你可以…

使用核心拖放API。这一级别非常低,为您提供了广泛的灵活性。您可以根据需要拖动组件、数据或各种内容

例如:

如果你真的喜欢冒险,你可以看看这些

你可以..

使用新的传输API。此API的目的是使围绕应用程序传输数据变得更容易。虽然从技术上讲,可以这样移动组件,但这不是它的意图

看看


有关更多详细信息…

在数据转储时玩得开心;)