title: Why does this simple Java Swing program freeze?
body: <p>Below is a simple Java Swing program that consists of two files:</p>
  
  <ul>
  <li><em>Game.java</em></li>
  <li><em>GraphicalUserInterface.java</em></li>
  </ul>
  
  <p>The graphical user interface displays a "New Game" button, followed by three other buttons numbered 1 to 3.</p>
  
  <p>If the user clicks on one of the numbered buttons, the game prints out the corresponding number onto the console. However, if the user clicks on the "New Game" button, the program freezes.</p>
  
  <p>(1) Why does the program freeze?</p>
  
  <p>(2) How can the program be rewritten to fix the problem?</p>
  
  <p>(3) How can the program be better written in general?</p>
  
  <h2>Source</h2>
  
  <p><em><strong>Game.java</em></strong>:</p>
  
  <pre><code>public class Game {
  
      private GraphicalUserInterface userInterface;
  
      public Game() {
          userInterface = new GraphicalUserInterface(this);
      }
  
      public void play() {
          int selection = 0;
  
          while (selection == 0) {
              selection = userInterface.getSelection();
          }
  
          System.out.println(selection);
      }
  
      public static void main(String[] args) {
          Game game = new Game();
          game.play();
      }
  
  }
  </code></pre>
  
  <hr>
  
  <p><em><strong>GraphicalUserInterface.java</em></strong>:</p>
  
  <pre><code>import java.awt.BorderLayout;
  
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  
  import javax.swing.JButton;
  import javax.swing.JFrame;
  import javax.swing.JPanel;
  
  public class GraphicalUserInterface extends JFrame implements ActionListener {
  
      private Game game;
      private JButton newGameButton = new JButton("New Game");
      private JButton[] numberedButtons = new JButton[3];
      private JPanel southPanel = new JPanel();
      private int selection;
      private boolean isItUsersTurn = false;
      private boolean didUserMakeSelection = false;
  
      public GraphicalUserInterface(Game game) {
          this.game = game;
  
          newGameButton.addActionListener(this);
  
          for (int i = 0; i &lt; 3; i++) {
              numberedButtons[i] = new JButton((new Integer(i+1)).toString());
              numberedButtons[i].addActionListener(this);
              southPanel.add(numberedButtons[i]);
          }
  
          getContentPane().add(newGameButton, BorderLayout.NORTH);
          getContentPane().add(southPanel, BorderLayout.SOUTH);
  
          pack();
          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          setLocationRelativeTo(null);
          setVisible(true);
      }
  
      public void actionPerformed(ActionEvent event) {
          JButton pressedButton = (JButton) event.getSource();
  
          if (pressedButton.getText() == "New Game") {
              game.play();
          }
          else if (isItUsersTurn) {
              selection = southPanel.getComponentZOrder(pressedButton) + 1;
              didUserMakeSelection = true;
          }
      }
  
      public int getSelection() {
          if (!isItUsersTurn) {
              isItUsersTurn = true;
          }
  
          if (didUserMakeSelection) {
              isItUsersTurn = false;
              didUserMakeSelection = false;
              return selection;
          }
          else {
              return 0;
          }
      }
  
  }
  </code></pre>
  
  <hr>
  
  <p>The problem results from using the <code>while</code> loop</p>
  
  <pre><code>while (selection == 0) {
      selection = userInterface.getSelection();
  }
  </code></pre>
  
  <p>in the <code>play()</code> method of <em>Game.java</em>.</p>
  
  <p>If lines 12 and 14 are commented out,</p>
  
  <pre><code>//while (selection == 0) {
      selection = userInterface.getSelection();
  //}
  </code></pre>
  
  <p>the program no longer freezes.</p>
  
  <p>I think the problem is related to concurrency. However, I would like to gain a precise understanding of why the <code>while</code> loop causes the program to freeze.</p>