【问题标题】:ImageIcon click and drag around the windowImageIcon 在窗口中单击并拖动
【发布时间】:2014-03-04 05:23:18
【问题描述】:

我正在尝试制作它,以便可以单击并拖动一个 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);
    }
}

谢谢。

【问题讨论】:

    标签: java drag-and-drop draggable imageicon


    【解决方案1】:

    问题是您正在混合范式...更不用说您似乎从未将lbl 添加到任何内容中,因此它永远不可能接收事件以及panel 受布局控制的事实经理,使移动组件变得非常困难......

    在 Swing 中,至少有 3 种不同的拖动方式,您使用哪种方式可以达到您想要达到的目的。

    你可以...

    使用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。这个非常低的级别并为您提供了多种灵活性。您可以根据需要拖动组件、数据或各种东西...

    例如:

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

    你可以..

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

    看看……

    更多详情...

    【讨论】:

    • 享受数据转储的乐趣 ;)
    猜你喜欢
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多