Java 只能添加JLabel背景或JPanel背景

Java 只能添加JLabel背景或JPanel背景,java,swing,jpanel,paintcomponent,pong,Java,Swing,Jpanel,Paintcomponent,Pong,我正在用Java制作我的第一个游戏。这也是第一次使用swing。我在将对象正确添加到帧时遇到困难 一些不相关的代码已从其他类中删除。可能缺少几个引用的组件 Main: public class Main { Ball ball = new Ball(); int yBall = 0; public static void main(String[] args) throws InterruptedException { Main main = new

我正在用Java制作我的第一个游戏。这也是第一次使用swing。我在将对象正确添加到帧时遇到困难

一些不相关的代码已从其他类中删除。可能缺少几个引用的组件

Main:

public class Main { 
    Ball ball = new Ball();
    int yBall = 0;

    public static void main(String[] args) throws InterruptedException {
        Main main = new Main();
        main.run();
        while (true) {
            main.ball(100);
        }
    }
    public void run() throws InterruptedException {
        Data data = new Data();
        Frame frame = new Frame(700, 500);
        test.setAngleX();
        frame.add(data, BorderLayout.CENTER);
    }
}
public class Ball extends JLabel{

Graphics g1;

int x = 325, y = 225;
int speed = 1;
int angleX = 0;
int angleY = 0;

public Ball() {
}

public void setAngleX() {

    angleX = ThreadLocalRandom.current().nextInt(-5, 5 + 1);    
    angleY = ThreadLocalRandom.current().nextInt(-1, 1 + 1);    

    if (angleX == 0) {
        setAngleX();
    }

    if (angleY == 0) {
        setAngleX();
    }
}

public void move() {

    if (x + angleX < 0) {
        angleX = speed;
    } else if (x + angleX > getWidth() - 25) {
        angleX = -speed;
    } else if (y + angleY < 0) {
        angleY = speed;
    } else if (y + angleY > getHeight() - 25) {
        angleY = -speed;
    }

    x = x + angleX;
    y = y + angleY;
}

public void Ball() throws InterruptedException {
    move();
    repaint();

    int sleepSpeed = angleX * speed;
    if (sleepSpeed < 0) {
        sleepSpeed = -sleepSpeed;

        Thread.sleep(10*sleepSpeed);
    }
}


@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.WHITE);
    g.fillOval(x, y, 25, 25);
}
public int SendY() {
    return y;
}
当我在数据(背景)后添加球时,我的球在帧上可见,与我的数据重叠。如果我在这里切换位置,我的数据将可见,但我的球不可见,球仍然存在于下方。 帧。添加(球); frame.setVisible(true)

这是我的框架,我知道这里没有问题:

public class Frame extends JFrame {
    private int frameWidth;
    private int frameHeight;
    int yBall = 0;

    public Frame(int frameWidth, int frameHeight) {
        this.frameWidth=frameWidth;
        this.frameHeight = frameHeight;

        setSize(new Dimension(frameWidth, frameHeight));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }
}
这是我的球。paintComponent已经结束了,在此之前,它只是工作逻辑,我猜这与逻辑无关

球:

public class Main { 
    Ball ball = new Ball();
    int yBall = 0;

    public static void main(String[] args) throws InterruptedException {
        Main main = new Main();
        main.run();
        while (true) {
            main.ball(100);
        }
    }
    public void run() throws InterruptedException {
        Data data = new Data();
        Frame frame = new Frame(700, 500);
        test.setAngleX();
        frame.add(data, BorderLayout.CENTER);
    }
}
public class Ball extends JLabel{

Graphics g1;

int x = 325, y = 225;
int speed = 1;
int angleX = 0;
int angleY = 0;

public Ball() {
}

public void setAngleX() {

    angleX = ThreadLocalRandom.current().nextInt(-5, 5 + 1);    
    angleY = ThreadLocalRandom.current().nextInt(-1, 1 + 1);    

    if (angleX == 0) {
        setAngleX();
    }

    if (angleY == 0) {
        setAngleX();
    }
}

public void move() {

    if (x + angleX < 0) {
        angleX = speed;
    } else if (x + angleX > getWidth() - 25) {
        angleX = -speed;
    } else if (y + angleY < 0) {
        angleY = speed;
    } else if (y + angleY > getHeight() - 25) {
        angleY = -speed;
    }

    x = x + angleX;
    y = y + angleY;
}

public void Ball() throws InterruptedException {
    move();
    repaint();

    int sleepSpeed = angleX * speed;
    if (sleepSpeed < 0) {
        sleepSpeed = -sleepSpeed;

        Thread.sleep(10*sleepSpeed);
    }
}


@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.WHITE);
    g.fillOval(x, y, 25, 25);
}
public int SendY() {
    return y;
}
因此,我要么在帧上获取数据(背景),要么让球在空背景上弹来弹去,这取决于我最后在主帧中添加的背景。我猜这是重叠的bcz,但无论我搜索了多少,我都找不到适合我的代码的解决方案

我要么在帧上获取数据(背景),要么让球在空背景上弹来弹去,这取决于我最后在主帧中添加的背景

不能将这两个组件都添加到框架中。您需要有一个父/子关系

所以逻辑应该是这样的:

background.add( ball );
frame.add( background );
然后将绘制框架,然后是背景,最后是球

此外,Ball类还需要实现
getPreferredSize()
方法,以便组件具有合理的大小。在“绘制组件”方法中,应该在偏移(0,0)处绘制球。如果要在背景面板上移动球,则只需在球上使用setLocation(…)在背景上重新定位球。创建球时,还需要将球的大小设置为首选大小,以便球具有要在背景面板上绘制的大小/位置。背景面板的布局需要设置为null,以便您可以围绕面板自由移动球

您不应该扩展JLabel,您没有使用JLabel的任何功能。您正在进行自定义绘制,因此只需扩展JPanel或JComponent即可。有关更多信息和工作示例,请阅读上Swing教程的部分

此外,方法名称不应以大写字符开头
Ball()
不是正确的方法名。它看起来像类名。方法应该更具描述性

或者另一种方法,不是有两个组件,而是有一个组件。然后该组件的
paintcomponent(…)
方法将同时绘制以下两种内容:

  • 背景

  • 然后,通过这种方式,您可以相对于背景面板绘制球,这是您当前的逻辑工作方式。

    当您运行允许您查看球的版本时,尝试调整窗口大小并查看是否显示背景图像。如果不显示,则空背景会随之展开,反之亦然versa@zkalman,你看过所有的评论了吗,包括教程链接?。我正在给答案添加更多的信息。是的,我在回答你的信息之前回答了。当我添加getPreferredSize()时,它工作得非常好。非常感谢您的支持,以及其他部分!