0

我试图回答一个与在屏幕上移动球有关的问题,同时随着时间的推移改变它的颜色,但是我遇到了一个奇怪的错误,(很可能在我的代码中)并且在问这个问题时我遇到了一个相关的问题,但是问题是使用客户端-服务器架构,而我的只是一个运行自身的 Swing 应用程序。

正在发生的事情是,当圆/球(无论您想如何命名)达到半宽时,JPanel或者JFrame它变得不可见或停止。

起初我认为这可能是我JPanel的位置不好,但我添加了一个Border,所以我可以看到它的尺寸,但它显示了整个空间周围的整个边框JFrame

接下来我认为这可能是一些算术问题,所以我决定让球比我最初画的更大和更小,给我同样的结果,当我放大或缩小窗口大小时也有同样的问题。

为了获得以下输出,我需要更改增量9而不是10我最初添加的增量,因为如果我将其更改为10它变得不可见:

在此处输入图像描述

下面的代码产生上面的输出:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.util.Random;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class ChangingColorBall {
    private JFrame frame;
    private Timer timer;
    private BallPane ballPane;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new ChangingColorBall()::createAndShowGui);
    }

    private void createAndShowGui() {
        frame = new JFrame(getClass().getSimpleName());
        ballPane = new BallPane();

        timer = new Timer(100, e -> {
            ballPane.increaseX();
        });

        ballPane.setBorder(BorderFactory.createLineBorder(Color.RED));

        frame.add(ballPane);

        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        timer.start();
    }

    @SuppressWarnings("serial")
    class BallPane extends JPanel {
        private int x;
        private static final int Y = 50;
        private static final int SIZE = 20;
        private Color color;
        private Random r;

        public void increaseX() {
            x += 9;
            r = new Random();
            color = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
            revalidate();
            repaint();
        }

        public int getX() {
            return x;
        }

        public void setX(int x) {
            this.x = x;
        }

        public Color getColor() {
            return color;
        }

        public void setColor(Color color) {
            this.color = color;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;

            g2d.setColor(color);
//          g2d.fill(new Ellipse2D.Double(x, Y, SIZE, SIZE));
            g2d.fillOval(x, Y, SIZE, SIZE);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 100);
        }
    }
}

我还认为它可能与ShapesAPI 有关,并决定将其更改fillOval为同样的结果,我还不能发布 GIF,但如果需要,稍后会添加它。

我在 MacBook Pro(13 英寸 Retina 显示屏,2015 年初)上的 macOS Sierra 10.12.6 (16G29) 下工作,在 Java 1.8 下编译和运行它

我稍后也会在我自己的 PC 而不是我工作的 Mac 上测试此代码,但是,这可能是与 Swing 的 API 相关的错误还是我自己的代码中的错误?如果是这样,我做错了什么?因为我似乎不清楚

4

1 回答 1

4

问题是您无意中覆盖了类中getX()定义的方法。JComponentBallPane

因此,JPanel每当访问时的 x 坐标getX()也会发生变化,因为getX()现在返回您的字段x,该字段定义了球的移动方式,从而导致了这种行为。您应该getX()从中删除该方法BallPane或重命名它。

于 2017-10-16T22:39:41.283 回答