Java: метод Repaint() не вызывает paintComponent

Я делаю игру-разбиватель кирпичей и не могу заставить работать метод repaint(). Я использовал отладчик, и он не вызывает метод paintComponent. Я пытаюсь заставить весло двигаться влево или вправо при нажатии клавиш со стрелками влево/вправо. Поэтому я пытаюсь перерисовать графику, но мне не повезло, и я не могу понять, что я делаю неправильно.

Мой основной класс:

public class BrickBreakerGameApp {
    public static void main(String[] args) {
        int pw = 500;
        int ph = 900;
        GamePanel gPanel = new GamePanel(pw,ph);

        GameFrame gFrame = new GameFrame();
       
        gFrame.getContentPane().add(gPanel); //add game panel to frame
        
        gFrame.addKeyListener(new GamePanel(pw,ph)); //adds the key listener for the game panel frame
        
        gFrame.pack();
        gFrame.setVisible(true); //make frame visible
    }
}

Мой класс кадра:

import java.awt.Dimension;

import javax.swing.ImageIcon;
import javax.swing.JFrame;

public class GameFrame extends JFrame {
    //Global Variables
    public int frameWidth = 500;
    public int frameHeight = 800;
    
    //create constructor
    GameFrame () {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //so app closes properly
        this.setPreferredSize(new Dimension(frameWidth, frameHeight)); //set frame size
        this.setTitle("Brick Breaker Game");

        ImageIcon icon = new ImageIcon("res/brick-breaker-logo.jpg"); //create image icon
        this.setIconImage(icon.getImage()); //update frame icon

        this.pack();
    }
}


Мой класс панели:

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

/**
 * This class handles the game panel as a whole
 */

public class GamePanel extends JPanel implements ActionListener, KeyListener {

    // Global Variables
    private Ball ball;
    private Paddle paddle;
    private GameFrame gameFrame;
    private int width;
    private int height;

    // create a constructor
    GamePanel (int gamePanelWidth, int gamePanelHeight) {
    

        this.setWidth(gamePanelWidth);
        this.setHeight(gamePanelHeight);
        
        
        
        initialiseGame();
        this.isVisible();
        
    }


    private void initialiseGame() {
        ball = new Ball(10, 520, 30, 30); //create the ball object
        paddle = new Paddle(this, 50, 550, 100, 10); //creates paddle object
        
    }

    
    // paint all the elements in
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // background
        g.setColor(Color.black);
        g.fillRect(0, 0, getWidth(), getHeight());

        // paddle
        g.setColor(Color.CYAN);
        g.fillRect(paddle.getPaddleX(), paddle.getPaddleY(), paddle.getPaddleWidth(), paddle.getPaddleHeight());

        // ball
        g.setColor(Color.MAGENTA);
        g.fillOval(ball.getBallX(), ball.getBallY(), ball.getBallWidth(), ball.getBallHeight());

    }

    //add any unimplemented methods because we are using an interface
    @Override
    public void actionPerformed(ActionEvent e) {
        
    }

    @Override
    public void keyPressed(KeyEvent e) {
        

        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            paddle.moveLeft();
            
    
        }
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            paddle.moveRight();
            
        }
        this.repaint();
        
        
    }

 
    
    


    @Override
    public void keyTyped(KeyEvent e) {  
    }
    
    @Override
    public void keyReleased(KeyEvent e) {   
    }
    
    //create get and set methods for all paddle attributes
    public int getWidth() {
        return width;
    }

    public void setWidth(int pWidth) {
        this.width = pWidth;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int pHeight) {
        this.height = pHeight;
    }

    
}


Мой класс весла:

public class Paddle {
    //Global Variables
    private int paddleWidth;
    private int paddleHeight;
    private int paddleX; //paddle x position
    private int paddleY;
    private GamePanel gamePanel;
    
    //create paddle constructor
    Paddle() {

    }

    //create a paddle constructor based off parameters
    Paddle(GamePanel gPanel, int pX, int pY, int pWidth, int pHeight) {
        //set the values
        this.setPaddleWidth(pWidth);
        this.setPaddleHeight(pHeight);
        this.setPaddleX(pX);
        this.setPaddleY(pY);
        this.setGamePanel(gPanel);

    }

    //create get and set methods for all paddle attributes
    public int getPaddleWidth() {
        return paddleWidth;
    }

    public void setPaddleWidth(int pWidth) {
        this.paddleWidth = pWidth;
    }

    public int getPaddleHeight() {
        return paddleHeight;
    }

    public void setPaddleHeight(int pHeight) {
        this.paddleHeight = pHeight;
    }

    public int getPaddleX() {
        return paddleX;
    }

    public void setPaddleX(int pX) {
        this.paddleX = pX;
    }

    public int getPaddleY() {
        return paddleY;
    }

    public void setPaddleY(int pY) {
        this.paddleY = pY;
    }

    
    public GamePanel getGamePanel() {
        return gamePanel;
    }

    public void setGamePanel(GamePanel gPanel) {
        this.gamePanel = gPanel;
    }

    //move the paddle left if it is not already positoned at 0 (far left)
    public void moveLeft() {
        try {
            if (getPaddleX() <= 0) {
                setPaddleX(0);
                System.out.println("less than 0, x: " + getPaddleX());
                
            } 
            else if (getPaddleX() > 0) {
                setPaddleX(getPaddleX()-10); //to move paddle left -10
          //      gamePanel.repaint(getPaddleX()+10, getPaddleY(), getPaddleWidth(), getPaddleHeight()); //repaint old position
          //      gamePanel.repaint(getPaddleX(), getPaddleY(), getPaddleWidth(), getPaddleHeight()); //repaint new position
                System.out.println("left, x: " + getPaddleX());
              
            }
            
            
        }
        catch (Exception e) {
            
         }
        

    }

    

    //move the paddle right if it is not already positioned to the far right of the panel
    public void moveRight() {
        
        if (getPaddleX() >= gamePanel.getWidth() - getPaddleWidth()) { //dont move the paddle if it is on the right edge of the panel
            setPaddleX(gamePanel.getWidth() - getPaddleWidth());
            System.out.println("right1, x:" + getPaddleX());
            
        }
        else if ((getPaddleX()+getPaddleWidth()) <= gamePanel.getWidth()){ //if the paddle is within the panel bounds
            setPaddleX(getPaddleX() + 10); //to move paddle right +10
            System.out.println("right, x:" + getPaddleX());
        }
        
    }
}

GamePanel не фокусируется, поэтому он не может принимать ввод с клавиатуры.

VGR 10.12.2020 17:28

Не используйте KeyListener. Вместо этого вы должны использовать Key Bindings. См.: Движение с помощью клавиатуры для получения дополнительной информации и рабочих примеров.

camickr 10.12.2020 18:58

да, спасибо большое! и спасибо за информацию о привязках клавиш, ребята :)

LiL 11.12.2020 20:32
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
3
79
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После небольшого укуса отладки/тестирования я узнал, что в вашем основном методе:

public class BrickBreakerGameApp {
    public static void main(String[] args) {
        int pw = 500;
        int ph = 900;
        GamePanel gPanel = new GamePanel(pw,ph);

        GameFrame gFrame = new GameFrame();
       
        gFrame.getContentPane().add(gPanel); //add game panel to frame
        
        gFrame.addKeyListener(new GamePanel(pw,ph)); //adds the key listener for the game panel frame
        
        gFrame.pack();
        gFrame.setVisible(true); //make frame visible
    }
}

к вызову метода gFrame.addKeyListener добавьте не new GamePanel а тот, который вы уже создали, а именно:

gFrame.addKeyListener(gPanel); //adds the key listener for the game panel frame

Другие вопросы по теме