Newbie: Can't figure out why GUI is freezing
Hello, I am trying to make my very first program with Swing, and I cannot figure out why it freezes and what I need to do to prevent that from happening. This program simulates this game of life. If a button is selected (alive) and 2 or 3 (only) buttons surrounding it are also selected, then the button selected gets to stay selected. Otherwise it dies. Also, if an empty button is surrounded by exactly 3 selected button, it also becomes alive. Here is the code:
package learn;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
publicclass Life{
/**
* @author Michael Keselman
*/
final JLabel label =new JLabel("Empty");
finalstatic String LOOKANDFEEL ="System";
JToggleButton[] b =new JToggleButton[400];
JLabel message =new JLabel();
privateboolean f;
privatefinalint NUMRC = 20;// Number of Rows and Columns
publicstaticvoid main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
publicvoid run(){
createAndShowGUI();
}
});
}
publicstaticvoid createAndShowGUI(){
initLookAndFeel();
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame =new JFrame("Swing Application");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Life app =new Life();
Component contents1 = app.createComponents1();
Component contents2 = app.createComponents2();
frame.getContentPane().add(contents1, BorderLayout.CENTER);
frame.getContentPane().add(contents2, BorderLayout.SOUTH);
frame.pack();
frame.setSize(1200, 880);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public Component createComponents1(){
JPanel pane =new JPanel(new GridLayout(NUMRC, NUMRC));
for (int i = 0; i < 400; i++){
b[i] =new JToggleButton("" + i);
b[i].setForeground(Color.black);
pane.add(b[i]);
}
return pane;
}
public Component createComponents2(){
JPanel bpane =new JPanel();
JButton start =new JButton("Start!");
JButton stop =new JButton("Stop!");
stop.setToolTipText("Click here to stop the Game of Life");
start.setToolTipText("Click here to start the Game of Life");
start.addActionListener(new ActionListener(){
publicvoid actionPerformed(ActionEvent e){
SwingUtilities.invokeLater(new Runnable(){
publicvoid run(){
f =true;
while (f =true)
{
for (int i = 0; i < 400; i++){
try{
Thread.sleep(20);
}catch (InterruptedException g){
System.err.println(g);
}
int numSurround = getSurrounded(i);
if (b[i].isSelected())
{
if (numSurround < 2)
{
b[i].setText("L");
b[i].setToolTipText("Too Lonely");
b[i].setSelected(false);
}
elseif (numSurround > 3)
{
b[i].setText("C");
b[i].setToolTipText("Too Crowded");
b[i].setSelected(false);
}
}
else// not selected
{
if (numSurround == 3)
b[i].setSelected(true);
}
// try{Thread.sleep(3000);}
// catch(InterruptedException f){System.out.println(f);}
// System.out.println(i);
// message.setText("Success!");
//System.out.println(i);
//if (i == 399)
//i = -1;
}
}
}
});
}
});
stop.addActionListener(new ActionListener()
{
publicvoid actionPerformed(ActionEvent e)
{
System.out.println("Hello. Success.");
f =false;
}
});
bpane.add(message);
bpane.add(start);
bpane.add(stop);
return bpane;
}
privateint getSurrounded(int i){
int row = i / NUMRC;
int column = i % NUMRC;
int surroundCount = 0;
/*
* Left Neighbor
*/
int leftColumn = column - 1;
if (leftColumn >= 0){
if (b[getIndex(row, leftColumn)].isSelected())
++surroundCount;
}
/*
* Right Neighbor
*/
int rightColumn = column + 1;
if (rightColumn < NUMRC){
if (b[getIndex(row, rightColumn)].isSelected())
++surroundCount;
}
/*
* Top Neighbor
*/
int topRow = row - 1;
if (topRow >= 0){
if (b[getIndex(topRow, column)].isSelected())
++surroundCount;
}
/*
* Bottom Neighbor
*/
int bottomRow = row + 1;
if (bottomRow < NUMRC){
if (b[getIndex(bottomRow, column)].isSelected())
++surroundCount;
}
/*
* Upper-Left Neighbor
*/
if (topRow >= 0 && leftColumn >= 0){
if (b[getIndex(topRow, leftColumn)].isSelected())
++surroundCount;
}
/*
* Upper-Right Neighbor
*/
if (topRow >= 0 && rightColumn < NUMRC){
if (b[getIndex(topRow, rightColumn)].isSelected())
++surroundCount;
}
/*
* Bottom-Left Neighbor
*/
if (bottomRow < NUMRC && leftColumn >= 0){
if (b[getIndex(bottomRow, leftColumn)].isSelected())
++surroundCount;
}
/*
* Bottom-Right Neighbor
*/
if (bottomRow < NUMRC && rightColumn < NUMRC){
if (b[getIndex(bottomRow, rightColumn)].isSelected())
++surroundCount;
}
return surroundCount;
}
protectedint getIndex(int row,int column){
return (NUMRC * row + column);
}
privatestaticvoid initLookAndFeel(){
String lookAndFeel =null;
if (LOOKANDFEEL !=null){
if (LOOKANDFEEL.equals("Metal")){
lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
}elseif (LOOKANDFEEL.equals("System")){
lookAndFeel = UIManager.getSystemLookAndFeelClassName();
}elseif (LOOKANDFEEL.equals("Motif")){
lookAndFeel ="com.sun.java.swing.plaf.motif.MotifLookAndFeel";
}elseif (LOOKANDFEEL.equals("GTK+")){
lookAndFeel ="com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
}else{
System.err
.println("Unexpected value of LOOKANDFEEL specified: "
+ LOOKANDFEEL);
lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
}
try{
UIManager.setLookAndFeel(lookAndFeel);
}catch (ClassNotFoundException e){
System.err
.println("Couldn't find class for specified look and feel:"
+ lookAndFeel);
System.err
.println("Did you include the L&F library in the class path?");
System.err.println("Using the default look and feel.");
}catch (UnsupportedLookAndFeelException e){
System.err.println("Can't use the specified look and feel ("
+ lookAndFeel +") on this platform.");
System.err.println("Using the default look and feel.");
}catch (Exception e){
System.err.println("Couldn't get specified look and feel ("
+ lookAndFeel +"), for some reason.");
System.err.println("Using the default look and feel.");
e.printStackTrace();
}
}
}
}
I have a strong feeling that it is because of the semi-infinite for loop in the start button's ActionEvent, but I feel that the program needs to have this because it is supposed to go on until the user presses stop. Please help!
Thank you!!

