user3062868
user3062868

Reputation: 1

repaint() doesn't invoke paintComponent()

I'm trying to make a pong game in Java but it doesn't work. I've done some testing and it seems that the variables are updating but that when I do repaint(); in the timers actionPerformed(ActionEvent e) doesn't call the paintComponent() method

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

public class PongGame extends JComponent implements ActionListener, MouseMotionListener{

    public int state = 1;
    public int paddleX;
    public String buttonColor = "blue";
    public int mouseX, mouseY;
    private int ballX = 400;
    private int ballY = 150;

    public static void main(String[] args){

        JFrame window = new JFrame("Pong");
        PongGame game = new PongGame();
        window.add(new PongGame());
        window.pack();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setLocationRelativeTo(null);
        window.setResizable(false);
        window.setVisible(true);

        Timer t = new Timer(20, game);
        t.start();
    }

    public Dimension getPreferredSize(){
        return new Dimension(800, 600);
    }

    public void paintComponent(Graphics g){
        paddleX = mouseX;

        g.setColor(Color.WHITE);
        g.fillRect(0,0, 800, 600);

        g.setColor(Color.BLACK);

        g.fillRect(paddleX, 550, 150, 15);
        g.fillOval(ballX, ballY, 30, 30);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        ballX = ballX + 10;
        ballY = ballY + 10;
        System.out.println(ballX + " " + ballY);

    }

    @Override
    public void mouseDragged(MouseEvent e) {

    }

    @Override
    public void mouseMoved(MouseEvent e) {
        mouseX = e.getX();
        repaint();
    }
}

Upvotes: 0

Views: 141

Answers (4)

jitendra k
jitendra k

Reputation: 1

repaint() does not invoke paint() directly. It schedules a call to an intermediate method, update(). Finally, update() calls paint() (unless you override update).

The reason for this complexity is Java's support for concurrent programming. It does this using threads.

Using repaint() can be tricky for at least three reasons.

  1. the interaction between repaint() and the spontaneous painting done by the GUI thread
  2. the fact that repaint() just asks the thread system to schedule a call to update()/paint() and then exits. The repaint() method is asynchronous.
  3. the problem of preventing your drawing from being erased when being updated.

I suggest you to try the same with update().

Useful link : http://www.scs.ryerson.ca/~mes/courses/cps530/programs/threads/Repaint/index.html

Upvotes: 0

Sage
Sage

Reputation: 15408

  • you haven't registered the implemented MouseMotionListener to any component:

    game.addMouseMotionListener(game);
    
  • you are not adding your first created instance of PongGame to the frame rather added a new one producing bug:

     PongGame game = new PongGame();
      window.add(new PongGame());  // <<--- why creating the new instance ?
                  // it should be window.add(game);
    
  • As a good programming practice: try putting the add listener code in the component's own creating context i.e., in their constructor to make your code better readable.

Upvotes: 4

Andrew Thompson
Andrew Thompson

Reputation: 168815

To correct the actual problem. Add a constructor (tested locally):

PongGame() {
    addMouseMotionListener(this);
}

Upvotes: 1

tenorsax
tenorsax

Reputation: 21223

The problem is:

PongGame game = new PongGame();
window.add(new PongGame());

You have two instances of PongGame. One added to the frame (new PongGame()) and the other (game) that actually reacts to the timer. Change this row to:

window.add(game);

Upvotes: 1

Related Questions