matthewh86
matthewh86

Reputation: 314

Java AWT/Swing "contains" and "intersects" methods not working correctly

I'm attempting to teach myself some Java AWT and simple graphics but have had difficulty with using the contains and intersects method.

The problem is that it seems to detect the collision several pixels up from where the mouse is clicked and the actual shape.

GameDemo.java

package uk.co.mhayward.games.sandbox;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class GameDemo extends JFrame {

    GamePanel gamePanel = new GamePanel();

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

    public GameDemo() {
        super("click me");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.add(gamePanel);
        this.setSize(200, 200);

        this.setVisible(true);
        this.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent e) {}

            public void mousePressed(MouseEvent e) {
                System.out.println(e.getPoint().toString());
                if (gamePanel.shape.contains(e.getPoint())) {
                    System.out.println("IN");
                } else {
                    System.out.println("out");
                }
            }

            public void mouseReleased(MouseEvent e) {}

            public void mouseEntered(MouseEvent e) {}

            public void mouseExited(MouseEvent e) {}
        });
    }

    public class GamePanel extends JPanel {

        Shape shape = new RegularPolygon(100, 100, 100, 6, 0);

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D) g;

            g2d.setStroke(new BasicStroke(1));
            g2d.setPaint(Color.WHITE);
            g2d.fill(shape);
            g2d.setPaint(Color.BLACK);
            g2d.draw(shape);
        }
    }

    public static class RegularPolygon extends Polygon {
        private static final long serialVersionUID = 8828151557263250246L;

        /**
         * @param x
         * @param y
         * @param r
         * @param vertexCount
         */
        public RegularPolygon(int x, int y, int r, int vertexCount) {
            this(x, y, r, vertexCount, 0);
        }

        /**
         * @param x
         * @param y
         * @param r
         * @param vertexCount
         * @param startAngle
         *            360deg = PI
         */
        public RegularPolygon(int x, int y, int r, int vertexCount, double startAngle) {
            super(getXCoordinates(x, y, r, vertexCount, startAngle),
                    getYCoordinates(x, y, r, vertexCount, startAngle),
                    vertexCount);
        }

        protected static int[] getXCoordinates(int x, int y, int r, int vertexCount, double startAngle) {
            int res[] = new int[vertexCount];
            double addAngle = 2 * Math.PI / vertexCount;
            double angle = startAngle;
            for (int i = 0; i < vertexCount; i++) {
                res[i] = (int) Math.round(r * Math.cos(angle)) + x;
                angle += addAngle;
            }
            return res;
        }

        protected static int[] getYCoordinates(int x, int y, int r, int vertexCount, double startAngle) {
            int res[] = new int[vertexCount];
            double addAngle = 2 * Math.PI / vertexCount;
            double angle = startAngle;
            for (int i = 0; i < vertexCount; i++) {
                res[i] = (int) Math.round(r * Math.sin(angle)) + y;
                angle += addAngle;
            }
            return res;
        }
    }
}

EDITS

04/Jan/12 - changed Override paint(g) to paintComponent(g) - still doesn't detect collision properly. 05/Jan/12 - created a SSCCE to more easily demonstrate the problem.

Upvotes: 3

Views: 3977

Answers (4)

Russell Zahniser
Russell Zahniser

Reputation: 16364

Listen on the panel, rather than the JFrame. The offset you are seeing is from the titlebar.

Upvotes: 4

trashgod
trashgod

Reputation: 205865

For reference, this short example examines a transformed Polygon using the contains() method. The result seems correct to the nearest pixel. You might compare it to your result.

Upvotes: 5

Vishvjeet Kumar
Vishvjeet Kumar

Reputation: 11

you have override paintComponent(Graphics g) for Swing JComponents instead of method valid for AWT paint(Graphics g)

Upvotes: 1

mKorbel
mKorbel

Reputation: 109823

you have override paintComponent(Graphics g) for Swing JComponents instead of method valid for AWT paint(Graphics g), more in tutorials 2D Graphics and Performing Custom Painting

Upvotes: 2

Related Questions