ImageIcon click and drag around the window

旧街凉风 提交于 2019-12-12 06:33:26

问题


I'm trying to make it so I can click and drag an ImageIcon (in this case a card image but I'd like to learn how to do it generally) around the window but I don't really know how. I would like to be able to click and hold the mouse botton, drag the ImageIcon, and have stay where it is whn I release the mouse botton.

This is the code I have so far:

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

Thank you.


回答1:


The problem is you're mixing paradigms...not to mention you never seem to add lbl to anything, so it could never possible receive events and the fact that the panel is under the control of a layout manager, making moving a component very difficult...

In Swing there are at least three different ways to drag something, which you use comes down to what it is you want to achieve.

You can...

Use MouseListener and MouseMotitionListener to perform the actions manually. This is useful if you want to physical place an object somewhere within the container, like you are trying to do, for example...

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

}

You can...

Use the core Drag-n-Drop APIs. This very low level and provides you are wide variety of flexibility. You can drag components, data or sorts of stuff based on your needs...

For example:

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

And if you're really adventurous, you can take a look at these...

  • 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

You can..

Make use of the new transfer API. The intention of this API is to make it easier to transfer data around the application. While, technically, it would be possible to move a component this way, this is not it's intention.

Take a look at...

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

For more details...



来源:https://stackoverflow.com/questions/21616900/imageicon-click-and-drag-around-the-window

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!