javaswingpaintcomponentmouse-listeners

MouseMotionListener showing (x,y) offset


First of all, here is the related code:

    canvas = new CanvasPanel();
    canvas.setBackground(Color.white);
    canvas.addMouseListener(new PointListener());
    canvas.addMouseMotionListener(new PointListener());

    JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, canvas);


class CanvasPanel extends JPanel
{
    public void paintComponent(Graphics page)
    {
        super.paintComponent(page);

        if (mouseDragged == true)
        {
            page.drawRect(x1, y1, x3, y3);
            canvas.repaint();
        }
    }
}


class PointListener implements MouseListener, MouseMotionListener
{
    public void mousePressed (MouseEvent event)
    {
        mouseDragged = true;
        x1 = event.getX();
        y1 = event.getY();
    }
    public void mouseReleased (MouseEvent event)
    {
       // some code
    }

    public void mouseDragged(MouseEvent event)
    {
        x3 = event.getX();
        y3 = event.getY();
        canvas.repaint();
    }

So what this code is doing is when I click on the canvas component, it will draw an outline of a rectangle and the size changes as I drag the mouse

However, when I click and start to drag the mouse, there's an offset in the bottom right corner of the rectangle. It seems to jump to a bigger size the second I drag the mouse. Interestingly, the closer to the upper left corner of the canvas component I click, the closer the rectangle size is to the rectangle I draw with the mouse.

How can I fix this?


Solution

  • Remember, drawRect uses x, y, width, height as it's parameters, you should actually be using the delta between the click point and the drag point

    Maybe something like...

    public void paintComponent(Graphics page)
    {
        super.paintComponent(page);
    
        if (mouseDragged == true)
        {
            int x = Math.min(x1, x3);
            int y = Math.min(y1, y3);
            int width = Math.max(x1, x3) - x;
            int height = Math.max(y1, y3) - y;
            page.drawRect(x, y, width, height);
        }
    }
    

    And, don't call repaint from within the paint methods