Jack K
Jack K

Reputation: 483

Why won't the JPanels display?

I'm learning some swing and awt programming in Java so I decided to make Pong. The Main class is the parent JFrame. It instantiates a Ball and a Paddle and adds them (they are JPanels). However, only the last one added is displayed. How do I fix this?

Code:

public class Main extends JFrame {

public Main() {
    super("Pong");
    add(new Ball());
    add(new Paddle());

    setSize(500, 500);
    setBackground(Color.orange);
    setLocationRelativeTo(null);
    setResizable(false);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
}

public static void main(String[] args) {
    new Main().setVisible(true);
}

}

The Ball class:

public class Ball extends JPanel implements ActionListener {

Timer timer;
private Vec2d position;
private Vec2d velocity;
private Dimension ballSize;

public Ball() {
    super();
    position = new Vec2d(50, 50);
    velocity = new Vec2d(2, 3);
    timer = new Timer(25, this);
    ballSize = new Dimension(40, 40);

    timer.start();
}    


@Override
public void actionPerformed(ActionEvent ae) {
    //Perform game frame logic
    bounceBall();
    repaint(); 
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.fillArc((int)position.x, (int)position.y, ballSize.width, 
            ballSize.height, 0, 360);
    position.add(velocity);
}

private void bounceBall() {
    if(position.x < 0 || position.x > getWidth() - ballSize.width) {
        velocity.x *= -1;
    }

    if (position.y < 0|| position.y > getHeight() - ballSize.height) {
        velocity.y *= -1;
    }
}

}

And finally, the Paddle class:

public class Paddle extends JPanel implements ActionListener {

private Vec2d position;
private double yVelocity;

private Rectangle rect;

private Timer timer;


public Paddle() {
    super();
    position = new Vec2d(30, 250);
    yVelocity = 0;

    timer = new Timer(25, this);
    timer.start();
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.fillRect((int) position.x, (int) position.y, 20, 40);
}

@Override
public void actionPerformed(ActionEvent ae) {
    repaint();
}

}

Note that Vec2d is simply a small two dimensional Vector class I threw together. Also, the Pong logic (collision between Paddle and ball, scoring, etc) is not implemented. I just want to get it to draw correctly

Thanks in advance for the help!

Upvotes: 1

Views: 1117

Answers (4)

svdotbe
svdotbe

Reputation: 168

in the Paddle class, you never add the velocity to position with position.add(velocity) like you do in your ball class..

Upvotes: 0

Reimeus
Reimeus

Reputation: 159854

You are adding the Ball and Paddle to the same BorderLayout.CENTER position so only the last one added, (i.e. the Paddle) is displayed. You could use a GridLayout here to display:

setLayout(new GridLayout(1, 2));
add(new Paddle());
add(new Ball());

Upvotes: 1

JB Nizet
JB Nizet

Reputation: 692121

add(new Ball());
add(new Paddle());

By default, the layout manager of a JFrame is a BorderLayout. And if you don't specify where you want to add a component (BorderLayout.WEST, or EAST, etc.), the it's added at the center. So you add two components at the same place: in the center. So, only one of them is displayed.

Upvotes: 1

Russell Zahniser
Russell Zahniser

Reputation: 16364

The first thing to do is to add the JPanels to the content pane of your window, not to the window itself. I'm surprised you didn't get a runtime warning about that.

Also, it looks like you are planning to have each of your panels fill the screen, but paint only a small section of it. If that is really the way you want to do it, then you need to do setOpaque(false) on them so the panels under them can show through. But probably a better solution would be to have a single JPanel that is the drawing surface, and have its paintComponent() pass off the Graphics to each of the game objects to let them draw themselves.

Upvotes: 1

Related Questions