只能添加JLabel背景或JPanel背景

时间:2018-02-28 20:38:02

标签: java swing jpanel paintcomponent pong

我正在用Java开始我的第一场比赛。这是第一次使用swing。我无法正确地将对象添加到框架中。

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

主要

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

当我在数据(背景)后添加球时,我的球在框架上可见,与我的数据重叠。如果我在这里切换位置,我的数据将是可见的但不是我的球,球仍然存在于下方。         frame.add(球);         frame.setVisible(真);

public void ball(int yBall) throws InterruptedException {
    ball.Ball();
    yBall = ball.SendY();
}

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

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

最后是我的数据;

public class Data extends JPanel{
    private static final long serialVersionUID = 1L;
    private Graphics2D g2;
    public Data() {
    }
    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.BLACK);
        g2.fillRect(0, 0, getSize().width, getSize().height);
        g2.setColor(Color.lightGray);
        g2.fillRect(350, 0, 10, 400);
    }

所以会发生的事情是我要么在我的画面上得到我的数据(背景),要么让我的球在应有但是在空白背景下弹跳,这取决于我在主要内容中添加的最后一个。我猜它是重叠的bcz,但我无法找到适用于我的代码的解决方案,无论我搜索多少......

1 个答案:

答案 0 :(得分:1)

  

我要么在我的画面上得到我的数据(背景),要么让我的球在它应该弹跳,但是在空白的背景上,这取决于我在主画面中最后添加的那个。

您无法将两个组件添加到框架中。你需要有父/子关系。

所以逻辑应该是这样的:

background.add( ball );
frame.add( background );

然后画框,然后是背景,最后是球。

此外,Ball类需要实现getPreferredSize()方法,因此组件具有合理的大小。您应该在paint组件方法中以offset(0,0)绘制Ball。当你想在背景面板上移动球时,你只需在球上使用setLocation(...)将其重新定位在背景上。创建球时,您还需要将球的大小设置为首选大小,以便球具有要在背景面板上绘制的大小/位置。背景面板的布局需要设置为null,因此您可以在面板周围自由移动球。

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

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

或者另一种方法是拥有一个组件而不是两个组件。然后该组件的paintComopnent(...)方法将绘制两者:

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