Ваш reset()
метод:
static void reset() {
timer.cancel();
isPaused = false;
genNumber = 1;
header = new JPanel();
body = new CellGrid();
body.repaint();
timer = new Timer();
timer.schedule(new GameStep(), 0,1000);
}
Проблема - распространенная ошибка новичка ie - вы думаете, что изменение ссылки на переменную изменит предыдущий объект, на который изначально ссылалась переменная.
В частности, у вас есть body = new CellGrid();
, и это означает, что переменная тела ссылается на новый объект CellGrid, но (и это важная часть), она * ничего не делает с объектом CellGrid, который в данный момент отображается в вашем GUI, на который ранее ссылалась переменная тела.
Несколько альтернативных решений:
- Добавьте новый объект CellGrid, на который теперь ссылается переменная тела, в GUI в той же позиции BorderLayout, покрывая предыдущую
- Еще лучше не создавать новый объект CellGrid, а вместо этого создать способ вернуть текущий CellGrid в исходное состояние.
Например, возможно, если вы изменили CellGrid на ...
public class CellGrid extends JPanel implements Runnable{
private static final int ROWS = 60;
private static final int COLS = 60;
private static final int CELL_WIDTH = 10;
private Cell[][] cellGrid = new Cell[ROWS][COLS]; // make this non-static
public CellGrid() {
reset();
}
public void reset() {
cellGrid = new Cell[ROWS][COLS];
for (int row = 0; row < cellGrid.length; row++) {
for (int col = 0; col < cellGrid[row].length; col++) {
int x = col * CELL_WIDTH;
int y = row * CELL_WIDTH;
cellGrid[row][col] = new Cell(x, y, CELL_WIDTH);
if (new Random().nextBoolean()) {
cellGrid[row][col].setAlive(true);
} else {
cellGrid[row][col].setAlive(false);
}
}
}
}
// ..... more code below
Затем все, что вам нужно сделать, это вызвать reset()
для текущего объекта CellGrid, а затем вызвать repaint()
.
Другие проблемы:
- Вы чрезмерно используете модификатор stati c. Ничто в этой программе не должно быть stati c, кроме основного метода, ваших констант и все. Это может быть не важно для этой небольшой программы, но это станет важным позже, когда вы попытаетесь выполнить модульное тестирование или расширить или усовершенствовать эту программу или добавить ее в другую большую программу.
- Вы используете
java.util.Timer
и java.util.TimerTask
для запуска анимации l oop в программе Swing GUI, и это небезопасно, поскольку эти классы не безопасны для потоков Swing. Гораздо лучше использовать javax.swing.Timer
или «Swing Timer» вместо обоих этих классов для запуска анимации, так как это потокобезопасно для этой библиотеки GUI.