我正在尝试为网格中的每个单元格生成随机颜色(4种颜色之间)。我已设法这样做,但它不断重绘网格的轮廓和网格的其他元素。我怎样才能使颜色只画一次?,而我的其他元素一直在画画? 这是我目前的代码:
import java.awt.*;
import java.util.Random;
public class Cell extends Rectangle {
private Random random;
public Cell(int x, int y) {
super(x, y, 35, 35);
}
public void paint(Graphics g, Boolean highlighted) {
int row;
int col;
for (row=0; row < 20 ; row++ ) {
for (col =0; col <20 ; col++) {
x=col * 35;
y=row * 35;
SurfaceType(g);
}
}
g.setColor(Color.BLACK);
g.drawRect(x, y, 35, 35);
if (highlighted) {
g.setColor(Color.LIGHT_GRAY);
g.fillRect(x, y, 35, 35);
} else {
g.setColor(Color.DARK_GRAY);
g.fillRect(x, y, 35, 35);
}
}
@Override
public boolean contains(Point target){
if (target == null)
return false;
return super.contains(target);
}
public void SurfaceType(Graphics g) {
random= new Random();
int randomNumber = random.nextInt( 5);
switch (randomNumber) {
case 1: // dirt
g.setColor(new Color(102,51,0));
g.fillRect(x,y,34,34);
break;
case 2: //grass
g.setColor(new Color(102,153,0));
g.fillRect(x,y,34,34);
break;
case 3: //tree
g.setColor(new Color(0,102,0));
g.fillRect(x,y,34,34);
break;
case 4: //rock
g.setColor(new Color(182,182,182));
g.fillRect(x,y,34,34);
break;
}
}
}
此图显示当我取出随机化颜色的代码时网格的样子。
这一部分代码包括:
答案 0 :(得分:1)
事实上,这是我的答案:采用绘画代码的随机化 out 。相反,给Cell类一个方法,比如称为randomize()
,它执行颜色的随机化,只在你想要它被调用时被调用,并从你的绘画代码中删除那些代码。
为什么这很重要?了解到使用Swing,绘画并不完全在您的控制之下,您可以通过调用repaint()
来建议绘画,但不能保证总是会发生(特别是如果重新绘制请求) &#34; stack&#34;),有时操作系统会向JVM发出绘画请求,这完全不受你的控制。所以绘画方法应该只绘画而不是别的。任何显着改变对象状态的代码(例如随机化代码)都属于其他地方。
例如:
import java.awt.*;
import java.util.Random;
public class Cell extends Rectangle {
// no magic numbers
private static final Color DIRT_COLOR = new Color(102, 51, 0);
private static final Color GRASS_COLOR = new Color(102,153,0);
private static final Color TREE_COLOR = new Color(0, 102, 0);
private static final Color ROCK_COLOR = new Color(182, 182, 182);
private static final int CELL_WIDTH = 35;
private static final int RECT_WIDTH = CELL_WIDTH - 1;
private Color cellColor = null;
private Random random;
public Cell(int x, int y) {
super(x, y, CELL_WIDTH, CELL_WIDTH);
}
// highlighted should be a boolean primitive, not a Boolean wrapper
public void paint(Graphics g, boolean highlighted) {
int row;
int col;
// **** these nested for loops don't look right
// as this Cell should draw itself and only itself
for (row = 0; row < 20; row++) {
for (col = 0; col < 20; col++) {
x = col * CELL_WIDTH;
y = row * CELL_WIDTH;
// don't call surfactType() here, but rather *****
// simply draw with cellColor *******
if (cellColor != null) {
g.setColor(cellColor);
g.fillRect(x, y, RECT_WIDTH, RECT_WIDTH);
}
}
}
g.setColor(Color.BLACK);
g.drawRect(x, y, CELL_WIDTH, CELL_WIDTH);
if (highlighted) {
g.setColor(Color.LIGHT_GRAY);
g.fillRect(x, y, CELL_WIDTH, CELL_WIDTH);
} else {
g.setColor(Color.DARK_GRAY);
g.fillRect(x, y, CELL_WIDTH, CELL_WIDTH);
}
}
@Override
public boolean contains(Point target) {
if (target == null)
return false;
return super.contains(target);
}
// ** Rename this from SurfaceType to surfaceType
public void surfaceType() {
random = new Random();
int randomNumber = random.nextInt(5);
switch (randomNumber) {
case 1: // dirt
cellColor = DIRT_COLOR;
break;
case 2: // grass
cellColor = GRASS_COLOR;
break;
case 3: // tree
cellColor = TREE_COLOR;
break;
case 4: // rock
cellColor = ROCK_COLOR;
break;
}
}
}
现在,您的GUI代码可以在需要时调用surfaceType()
随机化单元格,并在状态更改后调用repaint()
。随机绘画不会改变单元格的状态。
您的代码的其他无关问题:
也许更干净的东西就是这样,使用枚举为你的地面:
import java.awt.Color;
public enum Ground {
DEFAULT(null), // Not sure if you need a default
DIRT(new Color(102, 51, 0)),
GRASS(new Color(102,153,0)),
TREE(new Color(0,102,0)),
ROCK(new Color(182,182,182));
private Ground(Color color) {
this.color = color;
}
private Color color;
public Color getColor() {
return color;
}
public static Ground getRandom() {
int randomIndex = (int) (Math.random() * Ground.values().length);
return Ground.values()[randomIndex];
}
}
和Cell2
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Stroke;
public class Cell2 {
private static final int CELL_WIDTH = 35;
private static final Stroke STROKE = new BasicStroke(3f);
private Rectangle rect; // favor composition over inheritance
private Ground ground;
public Cell2(int x, int y) {
rect = new Rectangle(x, y, CELL_WIDTH, CELL_WIDTH);
}
public void paint(Graphics2D g2, boolean highlighted) {
if (ground != null && ground != Ground.DEFAULT) {
g2.setColor(ground.getColor());
g2.fill(rect);
}
g2.setStroke(STROKE);
Color c = highlighted ? Color.LIGHT_GRAY : Color.DARK_GRAY;
g2.setColor(c);
g2.draw(rect);
}
public void randomizeGround() {
ground = Ground.getRandom();
}
public boolean contains(Point p) {
return rect.contains(p);
}
}