title: JPanels and handling events between them
body: <p>I'm creating a GUI which has the following panels:</p>
  
  <ol>
  <li><p>The Main frame which holds all the panels in the program:</p>
  
  <pre><code>public class Main extends JFrame {
      private Signup signupForm;
      private Login login;
      private UserScreen user;
      private JPanel cards;
      private CardLayout cl;  
  
      private static final int INNER_FRAME_WIDTH=800;
      private static final int INNER_FRAME_HEIGHT=800;
  
  
  /**
   * Launch the application.
   */
  public static void main(String[] args) {
      EventQueue.invokeLater(new Runnable() {
          public void run() {
              try {
                  Main frame = new Main();
                  frame.setVisible(true);
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      });
  }
  
  /**
   * Create the frame.
   */
  public Main() {
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setBounds(100, 100, INNER_FRAME_HEIGHT, INNER_FRAME_WIDTH);
      getContentPane().setLayout(new GridLayout(0, 1, 0, 0));
  
      cards = new JPanel();
      getContentPane().add(cards);
  
      cl = new CardLayout();
      cards.setLayout(cl);
  
      login = new Login();
      cards.add(login,"login");
  
  
      signupForm = new Signup();
      cards.add(signupForm,"signup");
  
      ActionListener listen = new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
          try{
              //check for a user with the parameters from userName and password fields . On success create a UserScreen for the current user.
              //This means that you need to send the User object to the UserScreen c'tor. It should look something like this. Might need to change UserScreen accordingly.
              user = new UserScreen();
              cards.add(user,"user");
              cl.show(cards,"user");
          }
          catch (Exception exception){ //TODO: Change to exception thrown from Client constructor
              //TODO: Have the exception popup the relevant screen.
          }
      }       
  
  };
  
      login.loginBtn.addActionListener(listen); &lt;&lt; Example of setting a button's actionListener from Main.
  
      setLoginListeners();
      setSignupListeners();
  }
  </code></pre>
  
  <p>}</p></li>
  <li><p>A Login panel - This is the screen you encounter when you open the program.</p></li>
  <li><p>A Signup panel - You get to this screen when pressing a 'signup' button in the login panel.</p></li>
  <li><p>A User's screen - A screen that display's a user's info.</p></li>
  </ol>
  
  <p>I've encountered an issue which I'm not sure how to handle:</p>
  
  <p>After clicking the 'Login' button in the Login panel, I want to switch to the new User's screen (UserScreen object).
  Since the class Login doesn't have access to the UserScreen object (only the Main frame does), I had to set the button's actionListener from the Main class which seemed like a terrible solution (since it required me to give the Main access to many fields from the Login panel so it can check if the user with the given username and password exists etc). Is there no better way?</p>
  
  <p>Is there a better solution than the one I've got?</p>