我目前正在尝试使用Swing用Java编写John Conway的生活游戏。但是,我在JPanel
中的GridLayout
单元中遇到了问题。这是有问题的代码
GameOfLifeFrame(int size, int generations, Random random, boolean[][] grid, final GameOfLife life) {
super("Game of life");
this.size = size;
this.generations = generations;
this.random = random;
this.grid = grid;
this.life = life;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300, 300);
var contentPane = getContentPane();
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
JLabel generationMaker = new JLabel("Generation: ");
add(generationMaker);
JLabel alive = new JLabel("Alive: 0");
add(alive);
var gridPanel = new JPanel();
gridPanel.setLayout(new GridLayout(size, size, 0, 0));
contentPane.add(gridPanel);
var cellArray = new javax.swing.JPanel[size][size];
for (var i = 0; i < size; i++) {
for (var j = 0; j < size; j++) {
var cell = new JPanel();
cellArray[i][j] = cell;
cell.setBorder(BorderFactory.createLineBorder(Color.BLACK));
gridPanel.add(cell);
}
}
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
var button = new JButton();
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
generateGrid(cellArray);
alive.setText("Alive: " + countAlive(life.grid));
incrementGeneration();
generationMaker.setText("Generation #" + generationCounter);
}
});
contentPane.add(button);
setVisible(true);
}
private void generateGrid(JPanel[][] cellArray) {
var grid2 = getGrid();
fillInPanels(cellArray, grid2);
life.grid = grid2;
}
protected void fillInPanels(javax.swing.JPanel[][] panelArray, boolean[][] grid) {
for (var i = 0; i < size; i++) {
for (var j = 0; j < size; j++) {
if (grid[i][j]) {
panelArray[i][j].setBackground(Color.BLACK);
} else {
panelArray[i][j].setBackground(Color.WHITE);
}
}
}
}
它运行良好,并且是Conway生活游戏的出色模拟器,但是它具有奇特的效果,即整个屏幕不会立即改变,但是您可以看到各个单元都在改变,并且不会立即改变,当我按下按钮时。这是因为有双重缓冲吗?当屏幕上的活动细胞较少时,即实际上开始快速运行时,它会更好地工作。
Here is how it is like on a 35 by 35 size grid
问题的根源是什么,我该如何解决?如果我在问题或帖子上的格式不佳,请原谅我,这是我第一次在此处发布。
答案 0 :(得分:0)
问题的原因是,每当我将瓷砖的油漆颜色从黑色更改为白色时,都会重新绘制网格,反之亦然。在执行setVisible
时将fillInPanels
设置为false,然后再将其设置为true解决了该问题。