我正在尝试使其能够在窗口周围单击并拖动一个ImageIcon(在这种情况下为卡片图像,但我想学习一般的用法),但我真的不知道如何做。我希望能够单击并按住鼠标按钮,拖动ImageIcon,并在释放鼠标按钮时留在原处。

这是我到目前为止的代码:

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,因此它永远不可能接收事件以及panel受布局管理器控制的事实,移动组件非常困难...

在Swing中,至少有三种不同的方式来拖动某些东西,而所使用的方法取决于您要实现的目标。

您可以...

使用MouseListenerMouseMotitionListener手动执行操作。例如,如果您想将对象物理放置在容器中的某个位置,这很有用,例如...

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

}


您可以...

使用核心的Drag-n-Drop API。此级别很低,可为您提供多种灵活性。您可以根据需要拖动组件,数据或各种东西...

例如:


java drag and drop
How to drag and drop JPanel with its components
move component after drag and drop


如果您真的很喜欢冒险,可以看看这些...


My Drag Image is Better than Yours
Drop Target Navigation, or You Drag Your Bags, Let the Doorman Get the Door
Smooth JList Drop Target Animation


您可以..

利用新的传输API。此API的目的是使在应用程序周围传输数据更加容易。从技术上讲,虽然可以通过这种方式移动组件,但这并不是故意的。

看一眼...


Drag and Drop and Data Transfer
Introduction to the DnD API
How to drag and drop with Java 2, Part 1


更多细节...

关于java - ImageIcon单击并在窗口中拖动,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21616900/

10-10 22:47