title: How do I implement a good game menu in Java?
body: <p>I have been working on a Java game for a while that I started back in my college days. After taking considerable breaks due to my professional career, I'm getting back to it and realizing how awful the code is. I basically had a "monolithic main" with both GUI and game logic in the same class file. What I'm attempting to do, is abstract and "componentize" the GUI into smaller chunks. My executed class extends <em>JFrame</em> which I add and remove panels to/from when buttons are clicked. Ex.</p>
  
  <pre><code>public class GameFrame extends JFrame{
      private JPanel[] _panels = {new MainPanel(), new OptionsPanel(), new DifficultyPanel()};
      private int _currentPanelIndex = 0;
      public GameFrame(){
          ...
          add(_panels[_currentPanelIndex]);
          ...
      }
  }
  </code></pre>
  
  <p>Within each panel class, I have private <em>ActionListeners</em> for the buttons. In <em>MainPanel</em>, I'm getting the singleton <em>GameFrame</em> instance and setting the current panel kind of like:</p>
  
  <pre><code>class SinglePlayerButtonListener implements ActionListener{
      public void actionPerformed(ActionEvent e){
          GameFrame instance = GameFrame.getInstance();
          JPanel[] panels = instance.getPanels();
          int currentPanelIndex = instance.getCurrentPanelIndex();
          instance.remove(panels[currentPanelIndex]);
          int newPanelIndex;
          for(newPanelIndex = 0; newPanelIndex &lt; panels.length; newPanelIndex++){
              if(panels[newPanelIndex] instanceof DifficultyPanel){
                  break;
              }
          }
          instance.add(panels[newPanelIndex]);
      }
  }
  </code></pre>
  
  <p>I do not like this deep of coupling in my classes, but I can live with it. However, the real problem is that when I click the last button that takes me into the game, I can't have:</p>
  
  <pre><code>public void actionPerformed(ActionEvent e){
      GameFrame.getInstance().startGame();
  }
  </code></pre>
  
  <p>because this will cause my game to run in the Java <em>Event</em> thread, thereby disallowing any other events from being handled. Previously, I had a busy while loop:</p>
  
  <pre><code>...
  while(waiting){
      //Do nothing
  }
  remove(_panels[_currentPanelIndex]);
  startGame();
  ...
  ...
  public void actionPerformed(ActionEvent e){
      waiting = false;
  }
  </code></pre>
  
  <p>What is the best way to let my <em>GameFrame</em> class know that I've clicked the play button? Can I send an event or message to it from one of its sub-panels telling it to start, and if so, how do I keep the game from running in the <em>Event</em> thread? Should I handle it in the <em>actionPerformed()</em> method and simply spawn a new thread? I would prefer to keep it in the main thread. Thanks.</p>