How can I drag images with the mouse cursor in Java GUI?
Asked Answered
C

2

5

// my code that calls upon n images in a directory to be placed on the JPanel

 public void imageAdder(int n, String name){
    BufferedImage myPic = null;
    for (int i = 0; i <= n; i++){
        try {
        myPic = ImageIO.read(new File("Images/" + name + i + ".jpg"));
        } catch (Exception e){
        System.out.println("no file man cmon");
        }
        JLabel picLabel = new JLabel(new ImageIcon(myPic));
      //  picLabel.setBounds(mouseX, mouseY, 100, 50);
      //  picLabel.addMouseMotionListener(this);
      //  picLabel.addMouseListener(this);
        canvas.add(picLabel);
    }}

I read about the class DragSource and how there's a method that drags things of type image, but I'm not sure if that's applicable given my code. What should I do if I wanted to freely drag the images with my mouse?

Cecillececily answered 13/1, 2015 at 5:5 Comment(0)
S
8

There are a number of ways you might achieve this...for example, you could use custom painting to paint the individual images yourself. Each time the mouse is pressed/dragged, you would need to calculate which image was been dragged.

A slightly simpler solution might be to use a JLayeredPane and continue using JLabels to render the images, you could then use a MouseListener and MouseMoitionListener to detect when a label was pressed and/or dragged and update it's position accordingly...

See How to Write a Mouse Listener and How to Use Layered Panes for more details.

Drag

import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestDrag {

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

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

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JLayeredPane {

        public TestPane() {
            File[] images = new File("C:\\hold\\thumbnails").listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    String name = pathname.getName().toLowerCase();
                    return name.endsWith(".png") || 
                                    name.endsWith(".jpg") || 
                                    name.endsWith(".bmp") ||
                                    name.endsWith(".gif");
                }
            });

            int x = 0;
            int y = 0;
            for (File imgFile : images) {

                try {
                    BufferedImage img = ImageIO.read(imgFile);
                    JLabel label = new JLabel(new ImageIcon(img));
                    label.setSize(label.getPreferredSize());
                    label.setLocation(x, y);
                    MouseHandler mh  = new MouseHandler();
                    label.addMouseListener(mh);
                    label.addMouseMotionListener(mh);
                    add(label);
                    x += 20;
                    y += 20;
                } catch (IOException exp) {
                    exp.printStackTrace();
                }

            }

        }

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

        public class MouseHandler extends MouseAdapter {

            private Point offset;

            @Override
            public void mousePressed(MouseEvent e) {
                JLabel label = (JLabel) e.getComponent();
                moveToFront(label);
                offset = e.getPoint();
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                int x = e.getPoint().x - offset.x;
                int y = e.getPoint().y - offset.y;
                Component component = e.getComponent();
                Point location = component.getLocation();
                location.x += x;
                location.y += y;
                component.setLocation(location);
            }

        }

    }

}
Shrike answered 13/1, 2015 at 5:21 Comment(6)
Hey, thank you for the response! I'm still really new to java and object oriented language, so I want to take a few days to understand the code you wrote and see if it can be implemented into my game. I will let you know soon how it goes, thanks so much for the help! I appreciate it.Cecillececily
It's only one way, the quickest and simplest I could think of, hope it helpsShrike
Hey this may seem like a dumb question, but each class should be in a separate file right? They way you arranged your brackets makes me think they are supposed to be in the same file because class testdrag is the last bracket in the code. But I was told that each class should have its own file. Please let me know when you can.Cecillececily
It's a self contained example, so it can reside within a single class, but it doesn't have to, because I'm using the source the event, the MouseHandler doesn't need to contained within the TestPane. These are know as inner classesShrike
Your code works like a charm! Thanks so much! Can I ask, if I wanted to separate the classes into different files in the same directory, would that cause any problems? I tried it and it couldn't recognize the method "moveToFront". Do you know any reason why that would be the case since movetofront is built in? (The imports shouldn't be a problem, I accounted for it)Cecillececily
Sorry for the late reply. moveToFront is a method of JLayeredPane, in order for the mouse listener to call it, it will need a reference to it. You could simply pass the reference directly, via the constructor for example, or, use the component that was clicked and use it's getParent method, which in this case, would return a JLayerdPane, (you'd need to cast the resulting Container to JLayerdPane)Shrike
P
0

Look at custom classes in Java Swing, possibly useful links to get you started:

Java2s - DragandDropSupportforImages

Drag Drop Image Screenshot

DragImage.java DropImage.java DragImageEvent.java

Preview answered 24/9, 2019 at 9:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.