Sam
Sam

Reputation: 93

Trouble using mouse to click on JComponent

Hey Everyone I am trying to create a somewhat dynamic program in which you can add shapes or images to a JPanel and then select and move the shapes after you have added them. The problem is that when I click on the specific JComponent nothing happens. In fact clicking on any of the components I have created to test the project returns false for all JComponents. However it seems that if I click inside the bounds of my JComponent in the top left corner I will get returned true for all JComponents, ie click in the area bounded by (0,0,50,68).

The idea is that if I click one of the JComponents it will set that specific JComponent to be movable however I cannot get past the part of actually selecting a specific JComponent.

Here is a basic SSCE that I built to recreate the problem:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class SSCE1 extends JPanel {
private ArrayList<Shape> shapeList = new ArrayList<Shape>();

SSCE1() {
    setLayout(null);
    /* Debug Stuff */
    System.out.println("Debug:");
    /* Add The First Shape To The List */
    shapeList.add(0, new Shape(100, 100));
    add(shapeList.get(0));
    shapeList.add(1, new Shape(610, 0));
    add(shapeList.get(1));
    shapeList.add(2, new Shape(500, 900));
    add(shapeList.get(2));

    addMouseListener(new MouseAdapter() {
        public void mouseClicked(MouseEvent e) {
            for (Shape shape : shapeList) {
                if (shape.contains(e.getPoint())) {
                    System.out.println("Hello");
                } else {
                    System.out.println("Goodbye");
                }
            }

        }
    });
}
}

class Shape extends JComponent {
int xLocation, yLocation, xBounds1, yBounds1;

Shape(int xLocation, int yLocation) {
    this.xLocation = xLocation;
    this.yLocation = yLocation;
    this.xBounds1 = 50;
    this.yBounds1 = 68;
    setBounds(xLocation, yLocation, xBounds1, yBounds1);
    setLocation(xLocation, yLocation);
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.blue);
    g.fillRect(0, 0, 100, 100);

}
}

class Run {

public static void main(String[] args) {
    JFrame main = new JFrame();
    SSCE1 p1 = new SSCE1();
    main.setSize(new Dimension(1000, 1000));
    main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    main.setLocation(new Point(0, 0));
    main.setVisible(true);
    main.add(p1);
}

}

Upvotes: 0

Views: 702

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347184

Basically, the problem is, Shape is expecting any mouse coordinates you pass it to be defined within the context of the Shape. That is, the top, left corner of Shape is always 0x0

The mouse point you are processing is within the context of the parent container, therefore, unless Shape is positioned at 0x0 within the parent container, Shape will never contain the mouse point.

You need to translate the mouse point to the context of the Shape before checking it

For example...

addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {
        for (Shape shape : shapeList) {
            Point shapePoint = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), shape);
            if (shape.contains(shapePoint) {
                System.out.println("Hello");
            } else {
                System.out.println("Goodbye");
            }
        }

    }
});

Upvotes: 3

alex2410
alex2410

Reputation: 10994

Use next mouseListener it works:

addMouseListener(new MouseAdapter() {
        public void mouseClicked(MouseEvent e) {
            for (Shape shape : shapeList) {
                Point convertPoint = SwingUtilities.convertPoint(SSCE1.this, e.getPoint(), shape);
                if (shape.contains(convertPoint)) {
                    System.out.println("Hello");
                } else {
                    System.out.println("Goodbye");
                }
            }

        }
    });

The reason is next according docs in contains method the point's x and y coordinates are defined to be relative to the coordinate system of this component. because of that works for (0,0,50,68). All what you need convert point from JPanel to Shape with help of SwingUtilities.convertPoint(...)

Upvotes: 1

Related Questions