gpt4 book ai didi

java - 如何在Java中阻止网格单元重绘?

转载 作者:行者123 更新时间:2023-12-02 12:19:29 25 4
gpt4 key购买 nike

我正在尝试为网格中的每个单元格生成随机颜色(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;
}



}


}

此图显示了当我取出随机颜色的代码时网格的样子。

enter image description here

这个显示了包含的那部分代码:

enter image description here

最佳答案

事实上,这就是我的答案:从绘画代码中取出随机化。相反,为 Cell 类提供一个方法,例如称为 randomize() 的方法,该方法执行颜色的随机化,并且仅在您希望调用时调用它,然后从绘画代码中删除该代码。

为什么这很重要?了解使用 Swing,绘画并不完全在您的控制之下,您可以建议通过调用 repaint() 来完成绘画,但不能保证总是发生(特别是在重新绘画的情况下)请求“堆栈”),有时操作系统会向 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()。随机绘画不会改变细胞的状态。

与您的代码无关的其他问题:

  • 带有嵌套 for 循环的绘制方法似乎试图绘制所有单元格而不仅仅是当前单元格,这看起来不正确。相反,它应该只关心绘画本身。
  • 您的代码不完全遵循 Java 命名约定,因为方法名称应以小写字母开头。
  • 您使用了大量“神奇”的数字和值,并且希望避免这样做,以便使您的代码更具 self 注释性。

也许更干净的是这样的,使用枚举作为你的地面:

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

关于java - 如何在Java中阻止网格单元重绘?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45899558/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com