I’m designing a simple ping pong game using Swing. The game is implemented by 5 .java files – PingPongApp.java an entry point for JVM, MainPanel.java a panel that organizes 2 sub-panels: a button panel and a screen panel (ScreenPanel.java), then Ball.java and Racket.java which implement the ball and racket logic. I’m trying to draw both the ball and racket on the screen panel but the problem is that somehow the ball is the only object that is drawn when I run the app. Here's my code:
Racket.java
import java.awt.*;
public class Racket{
public Racket(int x, int y, int width, int height){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public void draw(Graphics g){
g.setColor(Color.RED);
g.fillRect(x, y, width, height);
}
private int x, y, width, height;
}
Ball.java
import java.awt.*;
public class Ball{
public Ball(int x, int y, int velocityX, int velocityY){
this.x = x;
this.y = y;
this.velocityX = velocityX;
this.velocityY = velocityY;
}
public void setBounds(int width, int height){
rightBoundary = width - DIAMETER;
bottomBoundary = height - DIAMETER;
}
public void move(){
// Move the ball
}
public void draw(Graphics g){
g.fillOval(x, y, DIAMETER, DIAMETER)
}
private final static int DIAMETER = 21;
private int x, y, velocityX, velocityY, rightBoundary, bottomBoundary;
}
ScreenPanel.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class ScreenPanel extends JPanel{
public ScreenPanel(){
initComponents();
}
private void initComponents(){
interval = 35;
ball = new Ball(130, 0, 2, 3);
racket = new Racket(120, 250, 70, 10);
setPreferredSize(new Dimension(200, 200));
setBorder(BorderFactory.createLineBorder(Color.BLACK));
timer = new Timer(interval, new ActionListener(){
@Override
public void actionPerformed(ActionEvent evt){
ball.setBounds(getWidth(), getHeight());
ball.move();
repaint();
}
});
}
public void paintComponent(Graphics g){
super.paintComponent(g);
ball.draw(g);
racket.draw(g);
}
public void startOrPauseGame(boolean turnOnOff){
if(turnOnOff){
timer.start();
} else {
timer.stop();
}
}
private Racket racket;
private Timer timer;
private Ball ball;
private int interval;
}
MainPanel.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class MainPanel extends JPanel{
public MainPanel(){
initComponents();
}
private void initComponents(){
buttonPanel = new JPanel(new FlowLayout());
screenPanel = new ScreenPanel();
cmdStart = new JButton("Start/Resume");
cmdPause = new JButton("Pause");
addComponentsToPane();
}
public void addComponentsToPane(){
buttonPanel.add(cmdStart);
buttonPanel.add(cmdPause);
setLayout(new BorderLayout());
add(buttonPanel , BorderLayout.NORTH);
add(screenPanel , BorderLayout.SOUTH);
cmdStart.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent evt){
// Start the game
}
});
cmdPause.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent evt){
// Pause the game
}
});
}
private ScreenPanel screenPanel;
private JPanel buttonPanel;
private JButton cmdStart, cmdPause;
}
The problem is that the y coordinate for your racket is greater then the preferred size height of the panel ScreenPanel
:- 250 > 200:
racket = new Racket(120, 250, 70, 10);
^
setPreferredSize(new Dimension(200, 200));
making the racket draw offscreen.