Search code examples
javaawtmouseeventrepaintpaintcomponent

Mouse doesn't maintain it's position when frame is moved across the screen


Here is the code.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.Robot;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JPanel;


public class Paint extends JPanel implements MouseMotionListener, MouseListener {

    public Paint() {        
        setBackground(Color.RED);
        addMouseMotionListener(this);
        addMouseListener(this);
    }

    private boolean clicked = false;

    public void paintComponent (Graphics g) {
        super.paintComponent(g);
        PointerInfo a = MouseInfo.getPointerInfo();
        Point b = a.getLocation();
        int x = (int) b.getX() - 3;
        int y = (int) b.getY() - 23;

        if (clicked) {
            g.drawLine(x, y-5000, x,y+5000);
            g.drawLine(x+5000,y,x-5000,y);
            g.setColor(Color.white);
        }

        g.drawLine(x, y-5000, x,y+5000);
        g.drawLine(x+5000,y,x-5000,y);
        g.setColor(Color.black);




        // . . .
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        repaint();

    }

    @Override
    public void mouseMoved(MouseEvent e) {
        repaint();
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mousePressed(MouseEvent e) {
        clicked = true;
        repaint();

    }

    @Override
    public void mouseReleased(MouseEvent e) {
        clicked = false;
        repaint();

    }




}

public class Frame extends JFrame {

    public Frame() {
        this.setSize(500,500);
        this.setTitle("Test painting");
        this.setResizable(false);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);

        Paint panel = new Paint();

        this.add(panel);

        this.setVisible(true);
    }

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

    }



}

When I run the program, it looks like it works fine when the application is in the default position, but once I move the applet to where I like on the screen, the lines don't maintain the current mouse position on screen.

Can someone show me where I've gone wrong or how to fix this?


Solution

  • Painting is done from the context of the component. The Graphics context for any given component is translated so that the top, left corner is 0x0.

    MouseInfo.getPointerInfo().getLocation() is returning the location of the mouse on the screen, not the position relative to the component.

    While there is a way to fix it, a better solution would be to simply use a MouseMotionListener instead. The MouseEvent sent to this method has already been translated to the component coordinate space...

    public void mouseMoved(MouseEvent me) {
        myPoint = me.getPoint();
    }
    

    Then in you paintComponent method, simple refer to myPoint instead of trying to use MouseInfo