JPanel为什么不显示?

时间:2012-12-29 17:08:33

标签: java swing jframe awt

我正在学习Java中的一些swing和awt编程,所以我决定制作Pong。 Main类是父JFrame。它实例化一个Ball和一个Paddle并添加它们(它们是JPanels)。但是,仅显示添加的最后一个。我该如何解决这个问题?

代码:

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);
}

}

Ball类:

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;
    }
}

}

最后,Paddle课程:

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();
}

}

请注意,Vec2d只是一个小的二维Vector类,我将它们放在一起。此外,Pong逻辑(Paddle和球之间的碰撞,得分等)没有实现。我只想让它正确绘制

提前感谢您的帮助!

4 个答案:

答案 0 :(得分:1)

要做的第一件事是将JPanel添加到窗口的内容窗格中,而不是添加到窗口本身。我很惊讶你没有收到运行时警告。

此外,您似乎计划让每个面板都填满屏幕,但只绘制其中的一小部分。如果这是您想要的方式,那么您需要对它们setOpaque(false)进行操作,以便它们下面的面板可以显示出来。但是可能更好的解决方案是让一个JPanel作为绘图表面,让paintComponent()Graphics传递给每个游戏对象以让他们自己绘制。

答案 1 :(得分:1)

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

默认情况下,JFrame的布局管理器是BorderLayout。如果您没有指定要添加组件的位置(BorderLayout.WESTEAST等),则会将其添加到中心。所以你在同一个地方添加两个组件:在中心。因此,只显示其中一个。

答案 2 :(得分:1)

您要将BallPaddle添加到同一BorderLayout.CENTER位置,以便只显示添加的最后一个(即Paddle)。您可以在此处使用GridLayout来显示:

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

答案 3 :(得分:0)

在Paddle类中,你永远不会像在你的球类中那样用position.add(velocity)将速度添加到位置。