我对Java还比较陌生。
我需要做一个练习,用不同的位置和颜色画出不同的随机形状。我希望每个形状都有不同的颜色。这是我代码的一部分(有两种不同的形状,一种是椭圆形,另一种是矩形)。现在这两个形状有相同的随机颜色:
protected void paintComponent(Graphics g) {
int R = (int)(Math.random()*256);
int G = (int)(Math.random()*256);
int B = (int)(Math.random()*256);
Color color = new Color(R, G, B); // picks a random color
int ovalA = (int)(Math.random()*400);
int ovalB = (int)(Math.random()*300);
int ovalC = (int)(Math.random()*(400 - ovalA));
int ovalD = (int)(Math.random()*(300 - ovalB));
int rectA = (int)(Math.random()*300);
int rectB = (int)(Math.random()*400);
int rectC = (int)(Math.random()*(400 - rectA));
int rectD = (int)(Math.random()*(300 - rectB));
super.paintComponent(g);
g.setColor(color);
g.fillOval(ovalA, ovalB, ovalC, ovalD);
g.fillRect(rectA, rectB, rectC, rectD);
}
protected void paintComponent(Graphics g) {
int R = (int)(Math.random()*256);
int G = (int)(Math.random()*256);
int B = (int)(Math.random()*256);
Color color = new Color(R, G, B); // picks a random color
g.setColor(color);
int ovalA = (int)(Math.random()*400);
int ovalB = (int)(Math.random()*300);
int ovalC = (int)(Math.random()*(400 - ovalA));
int ovalD = (int)(Math.random()*(300 - ovalB));
g.fillOval(ovalA, ovalB, ovalC, ovalD);
R = (int)(Math.random()*256);
G = (int)(Math.random()*256);
B = (int)(Math.random()*256);
color = new Color(R, G, B); // picks a random color
int rectA = (int)(Math.random()*300);
int rectB = (int)(Math.random()*400);
int rectC = (int)(Math.random()*(400 - rectA));
int rectD = (int)(Math.random()*(300 - rectB));
super.paintComponent(g);
g.setColor(color);
g.fillRect(rectA, rectB, rectC, rectD);
}
现在,这是它背后的解释,当你按照你的方式编码时,你没有得到一组新的随机数字来表示你的颜色,即使你要求颜色,你使用的int也保持不变。我只是用math.random再次更改了这些值,然后用
p>目前,您正在为两个形状使用相同的Color
对象。您必须为每个应该用新颜色绘制的形状创建一个新的Color
对象。
我建议为此设置一个实用方法。这种方法大致如下所示:
private static final Random random = new Random(0);
private static Color createRandomColor() {
int r = random.nextInt(256);
int g = random.nextInt(256);
int b = random.nextInt(256);
Color color = new Color(r, g, b);
return color;
}
通过这种方式,您可以轻松绘制具有不同随机颜色的形状:
g.setColor(createRandomColor());
g.fillOval(ovalA, ovalB, ovalC, ovalD);
g.setColor(createRandomColor());
g.fillRect(rectA, rectB, rectC, rectD);
旁白:我通常建议使用java.util.Random
而不是Math.random
。主要原因是java.util.Random
提供了一些实用的方法,比如上面方法中使用的nextInt
方法,在这里非常方便。此外,Random
实例可以使用特定的种子创建,然后将始终返回相同的随机数序列,这可以使调试变得更容易(事实上,在某些情况下,只有这样才能使调试甚至成为可能!)。如果您再次想要"真实"随机数,您可以简单地创建Random
实例,而不需要种子。
编辑:Kevin Workman在他的评论中提出了一个重要的观点:
此外,您可能应该在paintComponent()方法之外初始化随机颜色,这样它就不会在每次重新绘制组件时发生变化。
但是,由于在每次调用paintComponent
期间,您也在随机创建形状,因此在调整窗口大小时,所有内容都会闪烁。
通常,paintComponent
方法应仅油漆。不应在那里读取或创建任何数据。对于您的应用程序案例,您可以通过创建包含Shape
对象的List
以及包含Color
对象的列表来解决此问题。我稍后将在这里添加一个示例。
编辑2:下面是一个例子:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class RandomShapePainter
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new RandomShapePanel());
f.setSize(600,600);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class RandomShapePanel extends JPanel
{
private final List<Shape> shapes;
private final List<Color> colors;
private static final Random random = new Random(0);
RandomShapePanel()
{
shapes = new ArrayList<Shape>();
colors = new ArrayList<Color>();
for (int i=0; i<5; i++)
{
shapes.add(createRandomShape());
colors.add(createRandomColor());
}
}
private static Shape createRandomShape()
{
boolean b = random.nextBoolean();
if (b)
{
return createRandomOval();
}
return createRandomRectangle();
}
private static Shape createRandomOval()
{
// Hard-coded constants should be avoided,
// just for illustration here
double x = 100+random.nextInt(300);
double y = 100+random.nextInt(300);
double w = 100+random.nextInt(300);
double h = 100+random.nextInt(300);
return new Ellipse2D.Double(x, y, w, h);
}
private static Shape createRandomRectangle()
{
// Hard-coded constants should be avoided,
// just for illustration here
double x = 100+random.nextInt(300);
double y = 100+random.nextInt(300);
double w = 100+random.nextInt(300);
double h = 100+random.nextInt(300);
return new Rectangle2D.Double(x, y, w, h);
}
private static Color createRandomColor()
{
int r = random.nextInt(256);
int g = random.nextInt(256);
int b = random.nextInt(256);
Color color = new Color(r, g, b);
return color;
}
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
for (int i=0; i<shapes.size(); i++)
{
Shape shape = shapes.get(i);
Color color = colors.get(i);
g.setColor(color);
g.fill(shape);
}
}
}