【问题标题】:Why won't the JPanels display?为什么 JPanel 不显示?
【发布时间】:2012-12-30 01:27:02
【问题描述】:

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

代码:

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

}

球类:

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 逻辑(桨与球之间的碰撞、得分等)未实现。我只是想让它正确绘制

提前感谢您的帮助!

【问题讨论】:

  • 顺便说一句,您的 Main 类永远不会创建您的 JPanel 实例。
  • 我出于调试目的将它们取出并忘记将它们放入问这个问题。 愚蠢的我!无论如何它都无法正常工作。
  • 您的Main 类不使用layoutManager。顺便说一句,如果您不明确使用布局管理器,它始终默认为 BorderLayout
  • +1 用于 SSCCE,与问题无关,但是,1) 不要扩展 JFrame 2) 不要在 JFrame 上调用 setSize,而是实现正确的 LayoutManager 和/或覆盖 @987654334 @ of JPanel 并返回适合图纸的正确尺寸,然后在将其设置为可见之前在 JFrame 上调用 pack()。 3) 始终通过 SwingUtiltities.invokeXXX 块在 Event Dispatch Thread 上创建 Swing 组件。
  • 正如 JB Nizet 和 Reimeus 所说,您正在将您的 JPanel 添加到相同的位置,我不相信您现在需要的是 LayoutManager,因为这是唯一一次 IMO @应该使用 987654340@ 您的实体是 Components 的扩展,而不是建模为实体的类(一个包含与 getX()getY() 等实体相关的属性的类)- 这是一个这样的例子逻辑:stackoverflow.com/questions/13999506/threads-with-key-bindings/…

标签: java swing jframe awt


【解决方案1】:

首先要做的是将JPanels 添加到窗口的内容窗格,而不是窗口本身。我很惊讶您没有收到关于此的运行时警告。

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

【讨论】:

  • 我创建了一个添加 JPanel 本身的 Board 类。有用。谢谢!
【解决方案2】:
add(new Ball());
add(new Paddle());

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 我刚刚尝试了 GridLayout 并显示了它们,但是一旦球越过屏幕的一半(并因此进入网格布局的第二列),它就会消失。
    【解决方案4】:

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

    【讨论】:

    • 我说我正在尝试修复一个绘图问题,但游戏逻辑尚未实现......
    猜你喜欢
    • 2017-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-06
    • 1970-01-01
    • 2012-08-08
    相关资源
    最近更新 更多