repaint()不会调用paintComponent()

时间:2013-12-13 18:15:25

标签: java swing repaint

我正在尝试用Java制作乒乓球游戏,但它不起作用。 我做了一些测试,似乎变量正在更新,但是当我这样做时 计时器repaint();中的actionPerformed(ActionEvent e)未调用paintComponent()方法

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();
    }
}

4 个答案:

答案 0 :(得分:4)

  • 您尚未将已实施的MouseMotionListener注册到任何组件:

    game.addMouseMotionListener(game);
    
  • 您没有将第一个创建的PongGame实例添加到框架中,而是添加了一个新的生成错误的实例:

     PongGame game = new PongGame();
      window.add(new PongGame());  // <<--- why creating the new instance ?
                  // it should be window.add(game);
    
  • 作为一个很好的编程实践:尝试将添加侦听器代码放在组件自己的创建上下文中,即在构造函数中使代码更易于阅读。

答案 1 :(得分:1)

问题是:

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

您有两个PongGame个实例。一个添加到帧(new PongGame())和另一个(game)实际上对计时器作出反应。将此行更改为:

window.add(game);

答案 2 :(得分:1)

纠正实际问题。添加构造函数(在本地测试):

PongGame() {
    addMouseMotionListener(this);
}

答案 3 :(得分:0)

repaint()不直接调用paint()。它调度对中间方法update()的调用。最后,update()调用paint()(除非你覆盖更新)。

这种复杂性的原因是Java对并发编程的支持。它使用线程执行此操作。

至少有三个原因,使用repaint()可能会很棘手。

  1. repaint()与GUI线程完成的自发绘画之间的交互
  2. repaint()只是要求线程系统安排调用update()/ paint()然后退出。 repaint()方法是异步的。
  3. 在更新时阻止您的绘图被删除的问题。
  4. 我建议你尝试使用update()。

    有用的链接:http://www.scs.ryerson.ca/~mes/courses/cps530/programs/threads/Repaint/index.html