【发布时间】:2014-12-24 11:43:55
【问题描述】:
这是一个很长的问题,请耐心等待。我正在制作一个 Game of Life 应用程序,它首先显示一个带有 JButton 网格的 JFrame。如果单击 JButton,它的背景会变黑,当再次激活时,它的背景会变回白色。我的代码:
public class Choose implements ActionListener {
public final static int DIMENSION = 50;
Color BLACK = new Color(0,0,0);
Color WHITE = new Color(255,255,255);
JFrame choose;
JButton[] choice;
JButton clear, fill, go;
JPanel baseChoose, baseFrame, buttonsAndText;
GridLayout base;
public Choose() {
choose = new JFrame("Make your own game");
choice = new JButton[DIMENSION*DIMENSION];
baseChoose = new JPanel();
baseChoose.setSize(500, 500);
buttonsAndText = new JPanel();
buttonsAndText.add(clear = new JButton("Clear"));
clear.addActionListener(this);
buttonsAndText.add(fill = new JButton("Fill"));
fill.addActionListener(this);
buttonsAndText.add(go = new JButton("Go"));
go.addActionListener(this);
base = new GridLayout(DIMENSION, DIMENSION);
base.setHgap(-1);
base.setVgap(-1);
baseChoose.setLayout(base);
choose.add(baseChoose);
choose.add(buttonsAndText);
JLabel text = new JLabel("Press 'Go' to start.");
buttonsAndText.add(text);
for (int i = 0; i < (DIMENSION*DIMENSION); i++) {
baseChoose.add(choice[i] = new JButton());
choice[i].setBackground(WHITE);
choice[i].addActionListener(this);
}
choose.setSize(500, 800);
choose.setVisible(true);
choose.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
choose.setResizable(false);
}
public void actionPerformed(ActionEvent e) {
JButton b = (JButton)e.getSource();
for (int i = 0; i < (DIMENSION*DIMENSION); i++) {
if (b == choice[i]) {
if (b.getBackground() == BLACK) {
choice[i].setBackground(WHITE);
} else if (b.getBackground() == WHITE) {
choice[i].setBackground(BLACK);
}
}
}
if (b == clear) {
for (int i = 0; i < (DIMENSION*DIMENSION); i++) {
choice[i].setBackground(WHITE);
}
choose.validate();
choose.repaint();
}
if (b == fill) {
for (int i = 0; i < (DIMENSION*DIMENSION); i++) {
choice[i].setBackground(BLACK);
}
choose.validate();
choose.repaint();
}
if (b == go) {
int states[] = new int[DIMENSION*DIMENSION];
for (int i = 0; i < DIMENSION*DIMENSION; i++) {
System.out.println(choice[i].getBackground() == BLACK);
if (choice[i].getBackground() == BLACK) {
states[i] = 1;
} else if (choice[i].getBackground() == WHITE) {
states[i] = 0;
}
}
choose.dispose();
Gui own = new Gui(states);
}
}
}
在我创建这个类的一个实例的 main 方法中,当您选择要激活的按钮后,您可以单击go 按钮来实际显示生命游戏。
public class Gui {
public final static int DIMENSION = 50;
Color BLACK = new Color(0,0,0);
Color WHITE = new Color(255,255,255);
JFrame frame, ownFrame;
JPanel baseFrame;
GridLayout base;
public Gui(int[] states) {
frame = new JFrame("Game of Life by Boris Verwoerd");
baseFrame = new JPanel();
baseFrame.setSize(500, 500);
frame.add(baseFrame);
base = new GridLayout(DIMENSION, DIMENSION);
base.setHgap(-1);
base.setVgap(-1);
baseFrame.setLayout(base);
JPanel[] box = new JPanel[DIMENSION*DIMENSION];
for (int i = 0; i < (DIMENSION*DIMENSION); i++) {
baseFrame.add(box[i] = new JPanel());
box[i].setBorder(BorderFactory.createLineBorder(Color.black));
}
frame.setSize(500, 500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.validate();
frame.repaint();
gameLoop(box, frame, states);
}
private static void gameLoop(JPanel[] boxes, JFrame theFrame, int[] states) {
int[] newstates = new int[DIMENSION*DIMENSION];
for (int i = 0; i < 20; i++) {
newstates = Maths.render(boxes, theFrame, states);
states = newstates;
theFrame.validate();
theFrame.repaint();
try {
Thread.sleep(100); //1000 milliseconds is one second.
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
public static int getDim() {
return DIMENSION;
}
}
按下 go 时,会启动一个新的 JFrame,但屏幕是全白的,只有在 gameLoop 结束后才会显示 JPanel 网格。
只有当我使用全零数组states 从主方法创建 Gui 实例时,它才能正确显示。
我已经尝试了很多方法来提出解决方案,但我不明白为什么它会导致这个白屏而不是网格。因此我的问题是:如何在从方法初始化时正确显示我的 Gui 实例,而不会出现白屏?
- 抱歉,帖子/代码太长了!
编辑:
这是我的数学课:
public class Maths {
static Color BLACK = new Color(0,0,0);
static Color WHITE = new Color(255,255,255);
public static int[] render(JPanel[] box, JFrame frame, int[] state) {
int[] newstates = new int[Gui.getDim()*Gui.getDim()];
for (int i = 0; i < (Gui.getDim()*Gui.getDim()); i++) newstates[i] = 0;
for (int i = (Gui.getDim()+1); i < (Gui.getDim()*Gui.getDim() - (Gui.getDim()+1)); i++) {
if (state[i] == 1) {
int aliveNeighbours = 0;
if (state[i-(Gui.getDim()+1)] == 1) aliveNeighbours++;
if (state[i-Gui.getDim()] == 1) aliveNeighbours++;
if (state[i-(Gui.getDim()-1)] == 1) aliveNeighbours++;
if (state[i-1] == 1) aliveNeighbours++;
if (state[i+1] == 1) aliveNeighbours++;
if (state[i+(Gui.getDim()-1)] == 1) aliveNeighbours++;
if (state[i+Gui.getDim()] == 1) aliveNeighbours++;
if (state[i+(Gui.getDim()+1)] == 1) aliveNeighbours++;
if (aliveNeighbours == 2 || aliveNeighbours == 3) {
box[i].setBackground(BLACK);
newstates[i] = 1;
} else {
box[i].setBackground(WHITE);
newstates[i] = 0;
}
} else if (state[i] == 0) {
int aliveNeighbours = 0;
if (state[i-(Gui.getDim()+1)] == 1) aliveNeighbours++;
if (state[i-Gui.getDim()] == 1) aliveNeighbours++;
if (state[i-(Gui.getDim()-1)] == 1) aliveNeighbours++;
if (state[i-1] == 1) aliveNeighbours++;
if (state[i+1] == 1) aliveNeighbours++;
if (state[i+(Gui.getDim()-1)] == 1) aliveNeighbours++;
if (state[i+Gui.getDim()] == 1) aliveNeighbours++;
if (state[i+(Gui.getDim()+1)] == 1) aliveNeighbours++;
if (aliveNeighbours == 3) {
box[i].setBackground(BLACK);
newstates[i] = 1;
} else {
box[i].setBackground(WHITE);
newstates[i] = 0;
}
}
}
return newstates;
}
}
【问题讨论】: