繁体   English   中英

repaint()不调用paintComponent()

[英]repaint() doesn't invoke paintComponent()

我正在尝试用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();
    }
}
  • 您尚未将实现的MouseMotionListener注册到任何组件:

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

      PongGame game = new PongGame(); window.add(new PongGame()); // <<--- why creating the new instance ? // it should be window.add(game); 
  • 作为一种好的编程习惯:尝试将添加侦听器代码放在组件自己的创建上下文中,即放在其构造函数中,以使您的代码更具可读性。

问题是:

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

您有两个PongGame实例。 一个添加到框架中( new PongGame() ),另一个添加到game (该game实际上对计时器做出反应)。 将此行更改为:

window.add(game);

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

PongGame() {
    addMouseMotionListener(this);
}

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

这种复杂性的原因是Java对并发编程的支持。 它使用线程来做到这一点。

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

  1. repaint()和GUI线程完成的自发绘画之间的交互
  2. repaint()只是要求线程系统安排对update()/ paint()的调用,然后退出这一事实。 repaint()方法是异步的。
  3. 防止您的图形在更新时被删除的问题。

我建议您使用update()尝试相同的操作。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM