我正在尝试使用 while 循环制作棋盘。然而,当我使用 while 循环时,瓷砖会出现一秒钟然后消失。
面板代码
package chess;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JPanel;
public class ChessBoard extends JPanel{
public int tileSize = 90;
public int cols = 8;
public int rows = 8;
public int maxCols = cols * tileSize;
public int maxRows = rows * tileSize;
TileManager tileM = new TileManager(this);
ChessBoard(){
this.setPreferredSize(new Dimension(maxCols, maxRows));
this.setBackground(Color.black);
this.setDoubleBuffered(true);
this.setFocusable(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
tileM.drawTiles(g2);
}
}
绘图代码
package chess;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.imageio.ImageIO;
public class TileManager {
ChessBoard cb;
public static int [] types = new int[10];
private static int rows = 0;
private static int cols = 0;
private boolean c = true;
String [] alpha = {"a", "b", "c", "d", "e", "f", "g", "h"};
String [] num = {"8", "7", "6", "5", "4", "3", "2", "1"};
TileManager(ChessBoard cb){
this.cb = cb;
}
public void drawTiles(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
while (rows < cb.rows && cols < cb.cols) {
if (c) g.setColor(Color.white);
if (!c) g.setColor(Color.black);
g2.setFont(new Font("Comic Sans", Font.BOLD, 20));
g2.fillRect(cols * cb.tileSize, rows * cb.tileSize, cb.tileSize, cb.tileSize);
g2.setColor(Color.green);
g2.drawString(alpha[cols], 5 + cols * cb.tileSize, 20 + rows * cb.tileSize);
g2.drawString(num[rows], 75 + cols * cb.tileSize, 85 + rows * cb.tileSize);
c = !c;
cols++;
if (cols == 8) {
c = !c;
cols = 0;
rows++;
}
}
}
}
这在很多层面上都是有问题的...
public class TileManager {
private static int rows = 0;
private static int cols = 0;
//...
public void drawTiles(Graphics g) {
//...
while (rows < cb.rows && cols < cb.cols) {
问问自己这个问题,下一次油漆通过会发生什么?
Swing 中的绘画具有破坏性。也就是说,在每个新的绘制过程中,您都应该从头开始完全重新绘制组件的状态。
paintComponent
要做的一件事是用组件的背景色填充Graphics
上下文。
所以,在随后的绘画过程中,
rows
和 cols
已经是 >=
cb.rows
和 cb.cols
所以你代表什么都不会画。
首先,删除
static
,它在这种情况下对您没有任何帮助,并且可能会给您带来更多问题,然后再解决。其次,rows
和 cols
不需要是实例级变量,它们的唯一作用是支持网格的绘制,所以你可以做局部变量代替。
例如...
public class TileManager {
ChessBoard cb;
public int[] types = new int[10];
private boolean c = true;
String[] alpha = {"a", "b", "c", "d", "e", "f", "g", "h"};
String[] num = {"8", "7", "6", "5", "4", "3", "2", "1"};
TileManager(ChessBoard cb) {
this.cb = cb;
}
public void drawTiles(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
int rows = 0;
int cols = 0;
while (rows < cb.rows && cols < cb.cols) {
if (c) {
g.setColor(Color.white);
}
if (!c) {
g.setColor(Color.black);
}
g2.setFont(new Font("Comic Sans", Font.BOLD, 20));
g2.fillRect(cols * cb.tileSize, rows * cb.tileSize, cb.tileSize, cb.tileSize);
g2.setColor(Color.green);
g2.drawString(alpha[cols], 5 + cols * cb.tileSize, 20 + rows * cb.tileSize);
g2.drawString(num[rows], 75 + cols * cb.tileSize, 85 + rows * cb.tileSize);
c = !c;
cols++;
if (cols == 8) {
c = !c;
cols = 0;
rows++;
}
}
}
}
我个人认为传递
TileManager
一个ChessBoard
的实例是不好的做法,你向TileManager
暴露了更多的功能然后它有任何管理责任。
就代码而言,我看不出有任何理由,但如果您确实需要
TileManager
从中提取信息,我会考虑编写一个 interface
来定义合同,或者,只需 ChessBoard
设置TileManager
的属性。任何返回通信都应该通过观察者模式完成(所以 TileManager
并告诉感兴趣的人,有些事情已经发生了)
我建议更加关注 AWT 和 Swing 中的绘画。
关于“为什么”它在一个平台上工作而不在另一个平台上工作的问题,欢迎来到这个美妙的世界,这就是不同平台的工作方式——但有些事情会触发 Swing 在初始绘制通过后执行一个或多个绘制通过。
当我测试它(在 MacOS 上)时,它一直有效,直到我尝试重新调整窗口大小。