ImageIcon 在窗口中单击并拖动

Posted

技术标签:

【中文标题】ImageIcon 在窗口中单击并拖动【英文标题】:ImageIcon click and drag around the window 【发布时间】: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);
    

谢谢。

【问题讨论】:

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

例如:

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

更多详情...

【讨论】:

享受数据转储的乐趣 ;)

以上是关于ImageIcon 在窗口中单击并拖动的主要内容,如果未能解决你的问题,请参考以下文章

在 Qt 中使用鼠标中键单击和拖动移动整个窗口

如何使用某个组合键+鼠标移动来调整窗口大小? (如 Linux 中的 Alt+F8)不单击并拖动

用右键单击或滚轮单击窗口在 Python Kivy 中添加红色可拖动圆圈

dephi中单击鼠标拖动窗口(使用WM_SYSCOMMAND)

JFrame.setBackground(Color)修改ImageIcon大小

拖动未修饰的 jDialog