PMH
PMH

Reputation: 85

why need call two repaints if only paint specific area?

I cannot figure out why I need to call repaint two times as in the below program. I expected that the first repaint will keep the rectangle as it was when I click in another position, and so now there are two rectangles in the window. But it actually removes the first rectangle. Can someone explain this?

class MyPanel extends JPanel {

    private int squareX = 50;
    private int squareY = 50;
    private int squareW = 20;
    private int squareH = 20;

    public MyPanel() {

        setBorder(BorderFactory.createLineBorder(Color.black));

        addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                moveSquare(e.getX(),e.getY());
            }
        });

        addMouseMotionListener(new MouseAdapter() {
            public void mouseDragged(MouseEvent e) {
                moveSquare(e.getX(),e.getY());
            }
        });

    }

    private void moveSquare(int x, int y) {
        int OFFSET = 0;
        if ((squareX!=x) || (squareY!=y)) {
            //repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
            repaint(squareX,squareY,squareW,squareH);
            squareX=x;
            squareY=y;
            repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
            //repaint(squareX,squareY,squareW,squareH);
        }
    }


    public Dimension getPreferredSize() {
        return new Dimension(250,200);
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawString("This is my custom Panel!",10,20);
        g.setColor(Color.RED);
        g.fillRect(squareX,squareY,squareW,squareH);
        g.setColor(Color.BLUE);
        g.drawRect(squareX,squareY,squareW,squareH);



  }
}

Upvotes: 1

Views: 46

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347314

It's all about timing. You are scheduling two different repaint requests, one for the area which the rectangle use to occupy and one for the area that the rectangle now occupies.

The repaint requests are pushed to the Event Queue (via the RepaintManager), which means that they occur some time in the future and are not immediately handled (within the method that is calling them).

This ensures that you are "erasing" the area where the rectangle "use" to be before you paint the area where the rectangle now is.

By using repaint(int, int, int, int) you reduce the amount of area which needs to be painted and can make the paint process more efficient.

Take a look at Painting in AWT and Swing for more details

Upvotes: 2

Related Questions