How to access ImageIcons in my mouseDragged event

2020-04-18 07:44发布

I'm trying to figure out how to access my different images, drawn with paintComponent, (using JLabels is not allowed in the assignment) in my events.

When dragging, I only want one image to move with my mouse drag and I cant seem to access "current image" with e.getSource().

My paintComponent will move all (3) images at the same time at the moment.

My question is: how to get hold of a single ImageIcon with my mouseDragged?

public class PhotoPanel extends JPanel implements MouseListener, MouseMotionListener {

private java.util.List<ImageIcon> myList = new ArrayList<>();
private int mx, my;

private ImageIcon image1 = new ImageIcon("src/resources/gira.gif");
private ImageIcon image2 = new ImageIcon("src/resources/stru.gif");
private ImageIcon image3 = new ImageIcon("src/resources/back.gif"); 

public PhotoPanel()
{
    setBackground(Color.GREEN);

    myList.add(image1);
    myList.add(image2);
    myList.add(image3);

    //Is this a problematic way of doin it?
    addMouseMotionListener(this);

}

public void paintComponent (Graphics g) {

    super.paintComponent(g);

    for (ImageIcon i : myList)
    {
       g.drawImage(i.getImage(), mx, my, this);
    }    
}


@Override
public void mouseDragged(MouseEvent e) {

    //if(e.getSource == image1)
    //{
    //    Manipulate single picture, but not working this way  
    //}
    mx = e.getX();
    my = e.getY();

    repaint();
    }    
}

3条回答
迷人小祖宗
2楼-- · 2020-04-18 07:58

I'm trying to figure out how to access my different images, drawn with paintComponent, (using JLabels is not allowed in the assignment) in my events

Since you can't use JLabels and if you want to get the current image being selected. You will have to iterate through the list of images add check which one is selected.

Currently you keep a list of ImageIcon, and there is no direct means to get the bounds of ImageIcon to check for selection.

If I were you, I will add a property (bounds) to the current ImageIcon to facilitate us to check whether an image is being clicked by the mouse:

class MyImages extends Rectangle
{
    private ImageIcon image;  //personally, I prefer to use BufferedImage here

    public MyImages(int x, int y, int width, int height){
        setBounds(x, y, width, height);
    }

    //getters & setters for image not shown

    public void draw(Graphics g){
        g.drawImage(image.getImage(), x, y, width, height, null);
    }

    //Check if current image is selected:
    public boolean isSelected(int xCoord, int yCoord){
        return (this.contains(xCoord, yCoord))
    }
}

In your PhotoPanel class:

//Crate a list of MyImage instead of ImageIcon
ArrayList<MyImage> myList = new ArrayList<MyImage>();
MyImage selectedImage;

In you MouseMotionListener class:

@Override 
public void mousePressed(MouseEvent e){

    //To get the image which is selected:
    for(MyImage img : myList)
        if(img.isSelected(e.getX(), e.getY())){  //if mouse clicks on this image
            selectedImage = img;    
            break;
        }
}

@Override
public void mouseDragged(MouseEvent e){
    if(selectedImage != null){
        selectedImage .setLocation(e.getX()-(pieceWH/2), e.getY()-(pieceWH/2));
        repaint();
    }
}

I maintain an instance call the selectedImage, and on mouse drag, we will change the location of selectedImage only. Hence only the last selected image will move.


In your paintComponent(g) method, you could just use .draw(g) if you created a customized Image class like MyImage:

@Override
protected void paintComponent(Graphics g){
    super.paintComponent(g);
    for (MyImage i : myList)
        i.draw(g);
}

This is a jig-saw puzzle I did with the same technique in the past:

enter image description here

查看更多
▲ chillily
3楼-- · 2020-04-18 08:07

Do not paint your images, use JLabels for displaying them.

JLabel imageLabel1 = new JLabel(image1);

If you add this to your panel it will show your image. You can reach your image by reaching labels. By the way, add your listener to all labels so getSource() will return you the related label.

查看更多
相关推荐>>
4楼-- · 2020-04-18 08:18

I'm seeing problems in several parts of the code. First of all, your images will always be drawn one on top of the other because

for (ImageIcon i : myList)
{
   g.drawImage(i.getImage(), mx, my, this);
}

mx and my are used for all the images. So you need each image to have its own coordinates.

The other part you're missing is code to determine what image is under the mouse when it is first clicked. You'll probably need to get the width and height of the images (and then calculate where the other corner is), but, after that, it's simple math to determine if the click x y is within the bounds of a rectangular image. Note that you will need to determine this for all three of the images.


The thing about getSource() that you need to realize is it returns the implicit parameter in the line addMouseMotionListener(this);

It's also a bit weird that your JPanel listens to itself.

查看更多
登录 后发表回答