java - JPanel 不会重新绘制生命游戏
问题描述
基本上我想做的就是当GUIoutput()
调用 Generation.java 中的方法时,它应该重新绘制 GameOfLife.java 中的面板。
但是,对于我尝试过的所有选项,例如使用javax.swing.Timer
to replace Thread.sleep
,它们都不起作用。将JPanel
与刚开始时相同。
package life;
public class Main {
public static void main(String[] args){
new Universe();
javax.swing.SwingUtilities.invokeLater(GameOfLife::new);
}
}
package life;
import static life.Universe.printUniverse;
public class Generation {
private static int[][] universe = Universe.getUniverse();
private static int size = Universe.getUniverse_size();
private static int M;
public Generation(){
Universe.setUniverse(evolution());
universe = Universe.getUniverse();
}
private void consoleOutput(){
//clear console first
/*
try {
if (System.getProperty("os.name").contains("Windows"))
new ProcessBuilder("cmd","/c","cls").inheritIO().start().waitFor();
else
Runtime.getRuntime().exec("clear");
}
catch (IOException | InterruptedException ignored) {}*/
//print out the statistics
System.out.println("Generation #" + M);
System.out.println("Alive: " + countAlive());
printUniverse();
}
public static int countAlive(){
int alive = 0;
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
if(universe[i][j] == 0){
alive++;
}
}
}
return alive;
}
private int[][] evolution(){
int[][] newUniverse = new int[size][size];
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
int[] cell = new int[]{i, j};
int neighboursAlive = cellDetector(cell);
//System.out.println("for cell: "+ Arrays.toString(cell)+" "+ neighboursAlive); //test with 3 36 err here
if(cellCondition(neighboursAlive, cell)){
newUniverse[i][j] = 0;//alive
}else{
newUniverse[i][j] = 1;//dead
}
}
}
return newUniverse;
}
private boolean cellCondition(int neighboursAlive, int[] cell){
int cellinUniverse = universe[cell[0]][cell[1]];
if(cellinUniverse == 0 && (neighboursAlive == 2 || neighboursAlive == 3)){
return true;
}else if(cellinUniverse == 1 && neighboursAlive == 3){
return true;
}
return false;
}
//correct
private int cellDetector(int[] cell){
//if not border cell
int i = cell[0];
int j = cell[1];
int neighboursAlive = 0;
if(i < size - 1 && i > 0
&& j < size - 1 && j > 0){
if(universe[i-1][j] == 0) neighboursAlive++;//N
if(universe[i-1][j+1] == 0) neighboursAlive++;//NE
if(universe[i+1][j] == 0) neighboursAlive++;//S
if(universe[i][j+1] == 0) neighboursAlive++;//E
if(universe[i+1][j+1] == 0) neighboursAlive++;//SE
if(universe[i-1][j-1] == 0) neighboursAlive++;//NW
if(universe[i][j-1] == 0) neighboursAlive++;//W
if(universe[i+1][j-1] == 0) neighboursAlive++;//SW
}else if(i == 0 && j > 0 && j < size - 1){
//top row
if(universe[i][j-1] == 0) neighboursAlive++;//W
if(universe[i+1][j-1] == 0) neighboursAlive++;//SW
if(universe[i+1][j] == 0) neighboursAlive++;//S
if(universe[i+1][j+1] == 0) neighboursAlive++;//SE
if(universe[i][j+1] == 0) neighboursAlive++;//E
if(universe[size-1][j] == 0) neighboursAlive++;//N
if(universe[size-1][j + 1] == 0) neighboursAlive++;//NE
if(universe[size-1][j - 1] == 0) neighboursAlive++;//NW
}else if(i == size - 1 && j > 0 && j < size - 1){
//bottom row
if(universe[i-1][j] == 0) neighboursAlive++;//N
if(universe[i-1][j-1] == 0) neighboursAlive++;//NW
if(universe[i-1][j+1] == 0) neighboursAlive++;//NE
if(universe[i][j+1] == 0) neighboursAlive++;//E
if(universe[i][j-1] == 0) neighboursAlive++;//W
if(universe[0][j] == 0) neighboursAlive++;//S
if(universe[0][j + 1] == 0) neighboursAlive++;//SE
if(universe[0][j - 1] == 0) neighboursAlive++;//SW
}else if(i > 0 && i < size - 1 && j == 0){
//first column
if(universe[i+1][j] == 0) neighboursAlive++;//S
if(universe[i-1][j] == 0) neighboursAlive++;//N
if(universe[i+1][j+1] == 0) neighboursAlive++;//SE
if(universe[i-1][j+1] == 0) neighboursAlive++;//NE
if(universe[i][j+1] == 0) neighboursAlive++;//E
if(universe[i+1][size-1] == 0) neighboursAlive++;//SW
if(universe[i][size-1] == 0) neighboursAlive++;//W
if(universe[i-1][size-1] == 0) neighboursAlive++;//NW
}else if(i > 0 && i < size - 1 && j == size - 1){
//last column
if(universe[i+1][j] == 0) neighboursAlive++;//S
if(universe[i-1][j] == 0) neighboursAlive++;//N
if(universe[i-1][j-1] == 0) neighboursAlive++;//NW
if(universe[i+1][j-1] == 0) neighboursAlive++;//SW
if(universe[i][j-1] == 0) neighboursAlive++;//W
if(universe[i+1][0] == 0) neighboursAlive++;//SE
if(universe[i][0] == 0) neighboursAlive++;//E
if(universe[i-1][0] == 0) neighboursAlive++;//NE
}else if(i == 0 && j == 0){
//up left corner
if(universe[i+1][j] == 0) neighboursAlive++;//S
if(universe[i+1][j+1] == 0) neighboursAlive++;//SE
if(universe[i][j+1] == 0) neighboursAlive++;//E
if(universe[size-1][0] == 0) neighboursAlive++;//N
if(universe[size-1][1] == 0) neighboursAlive++;//NE
if(universe[size-1][size-1] == 0) neighboursAlive++;//NW
if(universe[i][size-1] == 0) neighboursAlive++;//W
if(universe[i+1][size-1] == 0) neighboursAlive++;//SW
}else if(i == 0 && j == size - 1){
//up right corner
if(universe[i][j-1] == 0) neighboursAlive++;//W
if(universe[i+1][j-1] == 0) neighboursAlive++;//SW
if(universe[i+1][j] == 0) neighboursAlive++;//S
if(universe[0][0] == 0) neighboursAlive++;//E
if(universe[1][0] == 0) neighboursAlive++;//SE
if(universe[size-1][size-1] == 0) neighboursAlive++;//N
if(universe[size-1][size-2] == 0) neighboursAlive++;//NW
if(universe[size-1][0] == 0) neighboursAlive++;//NE
}else if(i == size - 1 && j == 0){
//bottom left corner
if(universe[i-1][j+1] == 0) neighboursAlive++;//NE
if(universe[i][j+1] == 0) neighboursAlive++;//E
if(universe[i-1][j] == 0) neighboursAlive++;//N
if(universe[0][size-1] == 0) neighboursAlive++;//SW
if(universe[0][0] == 0) neighboursAlive++;//S
if(universe[0][1] == 0) neighboursAlive++;//SE
if(universe[size-2][size-1] == 0) neighboursAlive++;//NW
if(universe[size-1][size-1] == 0) neighboursAlive++;//W
}else if(i == size - 1 && j == size - 1){
//bottom right corner
if(universe[i-1][j] == 0) neighboursAlive++;//N
if(universe[i-1][j-1] == 0) neighboursAlive++;//NW
if(universe[i][j-1] == 0) neighboursAlive++;//W
if(universe[0][size-2] == 0) neighboursAlive++;//SW
if(universe[0][size-1] == 0) neighboursAlive++;//S
if(universe[0][0] == 0) neighboursAlive++;//SE
if(universe[size-2][0] == 0) neighboursAlive++;//NE
if(universe[size-1][0] == 0) neighboursAlive++;//E
}
return neighboursAlive;
}
}
package life;
import javax.swing.*;
import java.awt.*;
public class GamePanel extends JPanel {
private static int size = Universe.getUniverse_size();
private static int[][] universe = Universe.getUniverse();
public GamePanel(){
universe = Universe.getUniverse();
setBounds(0, 40, 500, 500);
setBackground(Color.white);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
//500w && 500h
int WIDTH = 500/size;
int HEIGHT = 500/size;
for ( int x = 0; x <= 500; x += WIDTH ) {
for (int y = 0; y <= 500; y += HEIGHT) {
g.drawRect(x, y, WIDTH, HEIGHT);
}
}
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
if(universe[i][j] == 0){
g.fillRect(i*WIDTH, j*HEIGHT, WIDTH, HEIGHT);
}
}
}
}
}
package life;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
public class GameOfLife extends JFrame {
private static JLabel GLabel = new JLabel();
private static JLabel ALabel = new JLabel();
private static JPanel Panel = new JPanel();
private static int M = 0;
public GameOfLife() {
setTitle("Game of Life");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(516, 579);
setLayout(null);
setLocationRelativeTo(null);
GenerationLabel();
AliveLabel();
GamePanel();
setVisible(true);
}
private void GamePanel(){
Panel = new GamePanel();
add(Panel);
ActionListener refresh = e -> {
new Generation();
M++;
GLabel.setText("Generation #" + M);
ALabel.setText("Alive: " + Generation.countAlive());
Panel.repaint();
setVisible(true);
};
int UPDATE_SPEED = 700;
new Timer(UPDATE_SPEED, refresh).start();
}
private void GenerationLabel(){
GLabel.setName("GenerationLabel");
GLabel.setText("Generation #0");
GLabel.setBounds(5,0,100,20);
add(GLabel);
}
private void AliveLabel(){
ALabel.setName("AliveLabel");
ALabel.setText("Alive: " + Generation.countAlive());
ALabel.setBounds(5,20,100,20);
add(ALabel);
}
public static JLabel getALabel() {
return ALabel;
}
public static JLabel getGLabel() {
return GLabel;
}
public static JPanel getPanel() {
return Panel;
}
public static void setPanel(JPanel panel) {
Panel = panel;
}
}
package life;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class Universe {
private static int[][] universe;
private static int universe_size = 20;
private static long seed;
private static int M;
public Universe(){
setup();
populateUniverse();
}
private static void setup(){
//System.out.println("Please input universe parameters:");
Scanner scanner = new Scanner(System.in);
universe_size = 20; //scanner.nextInt();
//seed = scanner.nextLong();
//M = scanner.nextInt(); //num of gens
universe = new int[universe_size][universe_size];
for(int[] i: universe){
Arrays.fill(i, 1);
}
}
private static void populateUniverse(){
Random rand = new Random();
for(int i = 0; i < universe_size; i++) {
for (int j = 0; j < universe_size; j++) {
if(rand.nextBoolean()){
universe[i][j] = 0;
}
}
}
}
public static void printUniverse(){
for(int i = 0; i < universe_size; i++){
for (int j = 0; j < universe_size; j++){
if(universe[i][j] == 0){
System.out.print("O");//alive
}else if(universe[i][j] == 1){
System.out.print(" ");//dead
}
}
System.out.println();
}
}
public static int[][] getUniverse() {
return universe;
}
//public static int getM() {
// return M;
//}
public static int getUniverse_size() {
return universe_size;
}
public static void setUniverse(int[][] universe) {
Universe.universe = universe;
}
}
我试图删除线程并添加了一个计时器,但 JPanel 拒绝更新。
解决方案
哇,答案实际上是没有正确处理Universe变量,导致 JPanel 无法更新。哈哈。
推荐阅读
- visual-studio-code - 项目文件夹名称有空格时的纱线安装问题(链接不被识别为内部或外部命令、可运行程序或批处理文件)
- python - 为不同的文化/国家格式化 xlsx 日期列(英国与美国)
- python - 如何在具有不同会话的 selenium 中打开 chrome 中的多个选项卡
- firebase - 我们可以在应用程序处于审查模式时更改应用程序中的实时数据库吗?
- laravel - 试图在 laravel 中获取 Redis 键的值
- c# - 在 .net 核心应用程序中删除部分内存缓存值
- android - 如何为蓝牙广播实现自定义 UUID
- xamarin.forms - Xamarin Forms:视图模型中出现显示错误
- phpspreadsheet - 使用 Phpspreadsheet 将 Xlxs 文件转换为 Csv
- xml - Js2XML 在转换为 XML 时返回了额外的“item”标签