Java Swing: ¿cómo puedo implementar una pantalla de inicio de sesión antes de mostrar un JFrame?

Intento hacer un pequeño juego que primero muestre al jugador una pantalla de inicio de sesión simple donde puede ingresar su nombre (lo necesitaré más tarde para almacenar la información de estado del juego), dejar que elija un nivel de dificultad, etc., y solo lo hará muestre la pantalla principal del juego una vez que el jugador haya hecho clic en el botón reproducir. También me gustaría permitir que el jugador navegue a una colección de trofeos (con suerte para ellos bastante grande), del mismo modo en lo que les parecerá una nueva pantalla.

Hasta ahora tengo una ventana principal de juego con un diseño de cuadrícula y un juego que funciona (¡Yay para mí!). Ahora quiero agregar la funcionalidad anterior.

¿Cómo voy a hacer esto? No creo que quiera ir a la ruta múltiple de JFrame ya que solo quiero un icono visible en la barra de tareas a la vez (¿o establecería su visibilidad para que también afecte al icono?) En su lugar, creo y destruyo diseños o paneles o ¿algo como eso?

¿Cuáles son mis opciones? ¿Cómo puedo controlar qué contenido se muestra? ¿Especialmente teniendo en cuenta mis habilidades de novato?

Un diálogo modal simple como un JDialog debería funcionar bien aquí. La GUI principal que probablemente será un JFrame puede ser invisible cuando se invoca el diálogo, y luego configurarse como visible (suponiendo que el inicio de sesión fue exitoso) una vez que finaliza el diálogo. Si el diálogo es modal, sabrá exactamente cuándo el usuario ha cerrado el diálogo, ya que el código continuará justo después de la línea donde llama a setVisible (verdadero) en el cuadro de diálogo. Tenga en cuenta que la GUI en poder de un JDialog puede ser tan compleja y rica como la que tiene un JFrame.

Otra opción es usar un GUI / JFrame pero intercambiar vistas (JPanels) en la GUI principal a través de un CardLayout. Esto podría funcionar bastante bien y es fácil de implementar. Consulte el tutorial de CardLayout para obtener más información.

Ah, y bienvenidos a stackoverflow.com!

Aquí hay un ejemplo de un cuadro de diálogo de inicio de sesión como @HovercraftFullOfEels sugerido.

Nombre de usuario: stackoverflow Contraseña: stackoverflow

 import java.awt.*; import java.awt.event.*; import java.util.Arrays; import javax.swing.*; public class TestFrame extends JFrame { private PassWordDialog passDialog; public TestFrame() { passDialog = new PassWordDialog(this, true); passDialog.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new TestFrame(); frame.getContentPane().setBackground(Color.BLACK); frame.setTitle("Logged In"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.setExtendedState(JFrame.MAXIMIZED_BOTH); } }); } } class PassWordDialog extends JDialog { private final JLabel jlblUsername = new JLabel("Username"); private final JLabel jlblPassword = new JLabel("Password"); private final JTextField jtfUsername = new JTextField(15); private final JPasswordField jpfPassword = new JPasswordField(); private final JButton jbtOk = new JButton("Login"); private final JButton jbtCancel = new JButton("Cancel"); private final JLabel jlblStatus = new JLabel(" "); public PassWordDialog() { this(null, true); } public PassWordDialog(final JFrame parent, boolean modal) { super(parent, modal); JPanel p3 = new JPanel(new GridLayout(2, 1)); p3.add(jlblUsername); p3.add(jlblPassword); JPanel p4 = new JPanel(new GridLayout(2, 1)); p4.add(jtfUsername); p4.add(jpfPassword); JPanel p1 = new JPanel(); p1.add(p3); p1.add(p4); JPanel p2 = new JPanel(); p2.add(jbtOk); p2.add(jbtCancel); JPanel p5 = new JPanel(new BorderLayout()); p5.add(p2, BorderLayout.CENTER); p5.add(jlblStatus, BorderLayout.NORTH); jlblStatus.setForeground(Color.RED); jlblStatus.setHorizontalAlignment(SwingConstants.CENTER); setLayout(new BorderLayout()); add(p1, BorderLayout.CENTER); add(p5, BorderLayout.SOUTH); pack(); setLocationRelativeTo(null); setDefaultCloseOperation(DISPOSE_ON_CLOSE); addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); jbtOk.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (Arrays.equals("stackoverflow".toCharArray(), jpfPassword.getPassword()) && "stackoverflow".equals(jtfUsername.getText())) { parent.setVisible(true); setVisible(false); } else { jlblStatus.setText("Invalid username or password"); } } }); jbtCancel.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { setVisible(false); parent.dispose(); System.exit(0); } }); } } 

Te sugiero que insertes el siguiente código:

 JFrame f = new JFrame(); JTextField text = new JTextField(15); //the 15 sets the size of the text field JPanel p = new JPanel(); JButton b = new JButton("Login"); f.add(p); //so you can add more stuff to the JFrame f.setSize(250,150); f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

Inserta eso cuando quieras agregar las cosas. A continuación, agregaremos todas las cosas al JPanel:

 p.add(text); p.add(b); 

Ahora agregamos los ActionListeners para hacer que los JButtons funcionen:

 b.addActionListener(this); public void actionPerforemed(ActionEvent e) { //Get the text of the JTextField String TEXT = text.getText(); } 

No olvides importar lo siguiente si aún no lo has hecho:

 import java.awt.event*; import java.awt.*; //Just in case we need it import java.x.swing.*; 

Espero que todo lo que digo tenga sentido, porque a veces no lo hago (especialmente cuando estoy hablando de encoding / Java). Toda la importación (si no lo sabías) va en la parte superior de tu código.

En lugar de agregar el juego directamente a JFrame , puede agregar su contenido a JPanel (llamémoslo GamePanel ) y agregar este panel al marco. Haga lo mismo para la pantalla de inicio de sesión: agregue todo el contenido a JPanel ( LoginPanel ) y agréguelo al marco. Cuando tu juego comience, deberías hacer lo siguiente:

  1. Agregar LoginPanel al marco
  2. Obtener la entrada del usuario y cargar sus detalles
  3. Agregue GamePanel y destruya LoginPanel (ya que será bastante rápido volver a crear uno nuevo, por lo que no necesita mantener su memoria).