在以下代码中出现一些问题后,我能够创建一个变色球示例。
首先,panel.sleep(50);
让我思考(并且我通过您在评论中发布的DrawingPanel类链接确认)可能会变得危险,最好使用 aSwing Timer
代替,但是我不会假装使用或阅读所有类作为它太长了,所以在我在这里发布的示例中,我将使用 SwingTimer
方法。
另外,我不确定为什么new Color(int rgb)
使用随机int
(0到255之间)调用构造函数不会更新或Color
使用这些设置创建新的,然后在阅读了这个答案和另一个答案(我失去了它的链接,抱歉)之后,你可以使用new Color(float r, float g, float b)
,因此您可以将其与最多 . 的随机数一起使用256
。
您还可以将您的方法基于 MVC 模式,有一个模型Ball
类,其中包含坐标和Color
它将拥有的坐标,一个JPanel
将随着时间的推移绘制球的视图和一个将随着时间改变球的坐标和颜色的控制器。
免责声明:此示例只是水平移动球,并不会验证它是否在屏幕上,您需要根据自己的需要调整此示例。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
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;
private Ball ball;
public static void main(String[] args) {
SwingUtilities.invokeLater(new ChangingColorBall()::createAndShowGui); //We place our program on the EDT
}
private void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
ball = new Ball();
ballPane = new BallPane(ball);
timer = new Timer(100, e -> { //This Timer will execute every 100ms and will increase ball's X coord and paint it again.
ball.increaseX(); //This method increases X coord and changes ball's color on the model
ballPane.revalidate();
ballPane.repaint();
});
frame.add(ballPane);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
timer.start(); //We start the timer
}
class Ball {
private int xCoord;
private static final int Y = 50;
private static final int SIZE = 20;
private Color color;
private Random r;
public void increaseX() {
xCoord += 10; //Increases X coord
r = new Random();
color = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256)); //Generates a new random color
}
public int getXCoord() {
return xCoord;
}
public void setXCoord(int xCoord) {
this.xCoord = xCoord;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
@SuppressWarnings("serial")
class BallPane extends JPanel {
private Ball ball;
public BallPane(Ball ball) {
this.ball = ball;
}
@Override
protected void paintComponent(Graphics g) { //This method paints the ball according to the color it has and the actual coords it has
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(ball.getColor());
g2d.fillOval(ball.getXCoord(), Ball.Y, Ball.SIZE, Ball.SIZE);
}
@Override
public Dimension getPreferredSize() { //We should not call `.setSize(...)` method, so we override this one and call `.pack();`
return new Dimension(200, 100);
}
}
}
笔记
请注意不要将您的坐标称为x
或y
至少不要将它们的 getter 和 setter 称为getX()
or getY()
,否则您可能会遇到我在此答案开头链接的问题。
这是 GUI 外观的示例,我不能在我的计算机上制作 GIF,但如果您复制粘贴代码并查看它是如何工作的,那就更好了。

要更深入地了解自定义绘画如何在 Swing 中工作,请查看 Oracle 的课程:在 AWT 和 Swing 中执行自定义绘画和绘画教程。