问题描述
我做了《康威的人生游戏》。第一轮效果很好。白色和黑色面板的网格代表生命细胞和死亡细胞。刷新视图以显示每一代的更改。但是,当您单击“新建游戏”时,我将丢弃旧框架并调用游戏构造函数-创建一个新框架。问题是:框架保持空白,直到游戏结束(循环播放一定数量的世代),然后显示单元的最后状态。我使用了打印语句,可以看到程序正常运行。直到最后帧才显示任何内容。我的猜测是,在第一个游戏在主线程中运行之前,我会在main方法中创建游戏的实例。新游戏无法在主线程中运行,因此GUI被某种程度上阻止了。有人可以在这里向我指出正确的方向吗?
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.jdialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class GameOfLife extends WindowAdapter {
boolean [][] feld;
static JFrame view;
JPanel main,settings;
JMenuBar menubar;
JMenu menu;
JMenuItem newgame,help;
JPanel[][] panels;
static int field = 100;
static int generations = 20;
@Override
public void windowClosing(WindowEvent arg0) {
System.exit(0);
}
public GameOfLife(int s,int g){
// Create a random starting field with r rows and c columns
// field is always rectangular,g is number of generations
int r,c;
r = s;
c = s;
view = new JFrame();
main = new JPanel(new GridLayout(r,c));
// Panels are visual representation
// Feld is the model (ie boolean array,true = alive,false = dead)
panels = new JPanel[r][c];
feld = new boolean [r][c];
for(int i = 0; i < r; i++) {
for (int j = 0; j < c; j ++) {
if(i == 0 || j == 0 || i == r-1 || j == c-1) {
feld[i][j] = false;
panels[i][j] = new JPanel();
panels[i][j].setBackground(Color.BLACK);
main.add(panels[i][j]);
} else {
panels[i][j] = new JPanel();
int random = (int)(Math.random () * 2) + 1;
if (random == 1) {
feld[i][j] = true;
panels[i][j].setBackground(Color.WHITE);
} else {
feld[i][j] = false;
panels[i][j].setBackground(Color.BLACK);
}
main.add(panels[i][j]);
}
}
}
view.addWindowListener(this);
view.add(main);
view.setSize(new Dimension(600,600));
view.setLocationRelativeto(null);
// Creating the small menu
settings = new JPanel();
settings.setLayout(new FlowLayout());
JTextField size = new JTextField(3);
settings.add(size);
menubar = new JMenuBar();
menu = new JMenu("Menu");
newgame = new JMenuItem("New Game");
help = new JMenuItem("help");
newgame.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
view.dispose();
showOptionsDialog();
newGame(field,generations);
}
});
help.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
showHelpDialog();
}
});
menu.add(newgame);
menu.add(help);
menubar.add(menu);
view.setJMenuBar(menubar);
view.setVisible(true);
// run for number of generations
for (int i = 0; i < g; i++) {
print();
nextGeneration();
System.out.println();
}
} // End Constructor
public static void main(String[] args) {
newGame(field,generations);
}
public static void newGame(int s,int g) {
GameOfLife game = new GameOfLife(s,g);
}
void print() {
for (int i = 0; i < feld.length; i++) {
for (int j = 0; j < feld[i].length; j++) {
if (feld[i][j]) {
panels[i][j].setBackground(Color.WHITE);
System.out.print("o ");
} else {
panels[i][j].setBackground(Color.BLACK);
System.out.print(". ");
}
}
System.out.println();
}
main.revalidate();
try {
Thread.sleep(800);
} catch (InterruptedException e) {
// Todo Auto-generated catch block
e.printstacktrace();
}
}
public void nextGeneration() {
/*Zelle ij lebt weiter,wenn 2 oder 3 Nachbarn leben
* Zelle ij stirbt,wenn weniger als 2 oder mehr als 3 Nachbarn leben
* Eine tote Zelle ij wird lebendig,wenn 3 Nachbarn leben
* Die Randzellen ohne genau 8 Nachbarn sind immer tot.
* Aufgabe: Neues Feld für die nächste Generation gemäß der 4 Regeln erzeugen*/
boolean zwischenFeld [][] = new boolean [feld.length][feld[0].length];
// Den Rand ignorierend das innere Feld durchlaufen
for (int i = 1; i < feld.length - 1; i++) {
for (int j = 1; j < feld[i].length - 1; j++) {
// Wieviele Nachbarn leben?
int lebendeNachbarn = 0;
if (feld[i-1][j-1]) {lebendeNachbarn++;}
if (feld[i-1][j]) {lebendeNachbarn++;}
if (feld[i-1][j+1]) {lebendeNachbarn++;}
if (feld[i][j-1]) {lebendeNachbarn++;}
if (feld[i][j+1]) {lebendeNachbarn++;}
if (feld[i+1][j-1]) {lebendeNachbarn++;}
if (feld[i+1][j]) {lebendeNachbarn++;}
if (feld[i+1][j+1]) {lebendeNachbarn++;}
// Ist die Zelle ij lebendig?
if (feld[i][j] == true) {
// Dann wenn 2 oder 3 Nachbarn auchleben lebe weiter
if (lebendeNachbarn == 2 || lebendeNachbarn == 2) {
zwischenFeld[i][j] = true;
// Wenn mehr als 3 Nachbarn oder weniger als 2 dann sterbe
} else if (lebendeNachbarn > 3 || lebendeNachbarn < 2){
zwischenFeld[i][j] = false;
}
// Die Zelle ij ist tot:
} else {
// Erwache zum leben wenn 3 Nachbarn leben
if (lebendeNachbarn == 3) {
zwischenFeld[i][j] = true;
} else {
zwischenFeld[i][j] = false;
}
}
}
}
// Jetzt das Zwischenfeld in das originale Feld kopieren
// Den Rand nach wie vor ignorieren,der bleibt immer tot
for (int i = 1; i < feld.length - 1; i++) {
for (int j = 1; j < feld[i].length - 1; j++) {
feld[i][j] = zwischenFeld[i][j];
}
}
}
public static void showOptionsDialog() {
jdialog showOptionsDialog = new jdialog(view,true);
showOptionsDialog.setLocationRelativeto(view);
Panel dataPanel = new Panel(new GridLayout(0,1));
TextField sizefield = new TextField("Fieldsize (Def. 100)",3);
TextField genField = new TextField("Generations (Def. 20)",2);
dataPanel.add(sizefield);
dataPanel.add(genField);
showOptionsDialog.add(dataPanel,BorderLayout.norTH);
JButton confirmButton = new JButton("Confirm");
// Make a lokal ActionListener,its used for button
class Confirmlistener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// Accept user input for field-size and number of generations
if (sizefield.getText().length() < 5 && genField.getText().length() < 3) {
String strInput = sizefield.getText();
field = Integer.parseInt(strInput);
if(field < 0) {
field *= -1;
}
String strInput2 = genField.getText();
generations = Integer.parseInt(strInput2);
if(generations<0) {
generations*= -1;
}
showOptionsDialog.dispose();
} else {
sizefield.setText("too large or NaN");
}
}
}
Confirmlistener cl = new Confirmlistener();
confirmButton.addActionListener(cl);
sizefield.addActionListener(cl);
Panel buttonPanel = new Panel(new FlowLayout());
buttonPanel.add(confirmButton);
showOptionsDialog.add(buttonPanel,BorderLayout.soUTH);
showOptionsDialog.setPreferredSize(new Dimension(200,200));
showOptionsDialog.pack();
showOptionsDialog.setVisible(true);
}
public static void showHelpDialog() {
jdialog helpDialog = new jdialog(view,true);
helpDialog.setLocationRelativeto(view);
Panel dataPanel = new Panel(new FlowLayout());
JTextArea helptext = new JTextArea("The Game of Life.");
helptext.setText("My interpretation of Conway's Game of Life."
+ "Read the rules on Wikipedia:"
+ "https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life");
helptext.setEditable(false);
dataPanel.add(helptext);
helpDialog.setPreferredSize(new Dimension(200,200));
helpDialog.pack();
helpDialog.setVisible(true);
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)