JFrame getHeight() and getWidth() return 0

Googly_ picture Googly_ · Feb 5, 2014 · Viewed 7.1k times · Source

I'm making a simple pong game; and part of the collision mechanics require getting the width and height of the canvas to redirect the ball. However, getWidth() and getHeight() return 0 for some reason. Here's the main block of code.

package pong;

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

public class Main extends JPanel {

    static int gameSpeed = 10;
    Ball ball = new Ball(this);

    private void move() {
        ball.move();
    }

    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        ball.paint(g2d);
    }

    public static void main(String args[]) throws InterruptedException {
        JFrame frame = new JFrame("Pong");
        Main game = new Main();
        frame.add(game);
        frame.setSize(400, 400);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        while (true) {
            game.move();
            game.repaint();
            Thread.sleep(gameSpeed);
        }
    }
}

And here's the actual Ball class, which handles movement conditions.

package pong;

import javax.swing.*;
import java.awt.*;

public class Ball extends JPanel {

    int x = 1;
    int y = 1;
    int dx = 1;
    int dy = 1;
    private Main game;

    public Ball(Main game) {
        this.game = game;
    }

    void move() {
        System.out.println(getWidth() + getHeight());

        if (x + dx < 0) {
            dx = 1;
        }
        if (y + dy < 0) {
            dy = 1;
        }
        if (x + dx > (getWidth() - 30)) {
            dx = -1;
        }
        if (y + dy > (getHeight() - 30)) {
            dy = -1;
        }
        x = x + dx;
        y = y + dy;
    }

    public void paint(Graphics2D g) {
        g.fillOval(x, y, 30, 30);
    }
} 

EDIT: Problem solved, I simply didn't tell getWidth() and getHeight() what to refer to. Obviously, if I don't tell them what to get, they'll return null. Derp. The simple fix was to change them to game.getWidth() and game.getHeight(). Thanks for the help, though! All your inputs help in other areas as well. :)

Answer

mKorbel picture mKorbel · Feb 5, 2014
  1. Graphics/Java2D by default never returs reasonable Dimension, result is zero Dimension, you have to override getPreferredSize for JPanel, then getWidth/Height will return correct coordinates for JPanels' size.

  2. then to use JFrame.pack() instead of any sizing.

  3. override paintComponent for Swing JComponents, instead of paint(), inside paintComponent 1st. code line should be super.paintComponent, otherwise painting cumulated.

  4. never to use Thread.sleep(int) in Swing, nor for Custom painting or animations in Java7 and Swing, use Swing Timer instead endless loop stopped by Thread.sleep(int).