Java - Parar main mientras se ejecuta un JFram

 
Vista:
sin imagen de perfil
Val: 40
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Parar main mientras se ejecuta un JFram

Publicado por Fran (13 intervenciones) el 10/04/2021 12:46:36
Buenas.

Me explico: estoy haciendo un programa en el cual desde el 'main' llamo a un JFrame del cual tomo unos datos. EL asunto es que cuando llamo el JFrame, el 'main' se sigue ejecutando hasta que cierra el programa y si dejo un while no deja de abrirse una y otra vez el JFrame.

Hay algún código para parar el main mientras está ejecutando el JFrame?

Muchas gracias de antemano!
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Billy Joel
Val: 2.665
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Parar main mientras se ejecuta un JFram

Publicado por Billy Joel (874 intervenciones) el 10/04/2021 17:08:36
Para que quieres detener el main?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
-1
Comentar
sin imagen de perfil
Val: 40
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Parar main mientras se ejecuta un JFram

Publicado por Fran (13 intervenciones) el 11/04/2021 07:39:30
El programa que estoy construyendo es más grande que esta parte en la que tengo la duda. El programa tiene como dos partes:

1º- Accesos del administrador con usuario y contraseña en la que puede principalmente listar los datos que se introducen en la otra parte y dar comienzo a un concurso. Esta parte la he podido resolver decentemente usando JOptionPane.

2º- En este apartado se piden una serie de datos para registar un equipo para un concurso, además de crear usuario y contraseña. Aquí es dónde me quedo atascado porque la primera manera que se me ocurrió para hacerlo es con while o do-while y JOptionPane como GUI. Pero se piden muchos datos y para que el botón Cancel me devuelva al menú primero en el que se elige entrar como administrador o registrar equipo, resulta en muchos while anidados en otros (o al menos así es como me resulta a mí). Entonces se me ocurrió lo del JFrame con dos pantallas de diálogo, una para crear usuario y contraseña, y otra para el resto de datos (nombre del equipo, entrenador y jugadores). Pero me ocurre lo que expliqué en mi pregunta. Cuando llamo al JFrama, el resto del programa sigue corriendo.

No estoy seguro si pegar el código serviría de algo, porque ahora mismo es un lío de las cosas que voy intentando, además de tener muchas clases. Pero si para alguien le puede ser de ayuda, lo copio.

Muchas gracias de antemano!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Parar main mientras se ejecuta un JFram

Publicado por Kabuto (1378 intervenciones) el 11/04/2021 14:05:20
Hola.
El main no se puede detener, ni debería ser necesario detenerlo si se aplica la lógica adecuada.

Cuando se hace un programa con interfaz gráfica, lo ideal es usar UN ÚNICO JFrame y que el main se limite simplemente a construir ese JFrame y ponerlo en marcha. Nada más.

El resto de funciones, decisiones, etc.. ya deberían llevarse a cabo con paneles, ventanas JDialog (algo a medio camino entre un JFrame y un JOptionPane) y acciones según los eventos que ocurran (clickar botones y tal...)

No se en que ha de consistir tu programa, pero voy a escribirte un ejemplo muy rápido y sencillo que quizás te sirva de inspiración.

Será un JFrame muy sencillo con dos botones, uno para crear usuario y otro para registrar equipos.
No le voy a dar funciones a esos botones porque esto es solo un ejemplo, pero veremos que el botón de registrar equipos comenzará desactivado porque de momento, no hay ningún usuario que haya hecho login.

imagen_2021-04-11_133921

En la foto vemos que hay además una barra de menú para que el usuario pueda hacer login o logout.
Cuando se hace click para hacer login, aparece un JDialog que se superpone al JFrame principal y es ahí donde se piden los datos de acceso.


imagen_2021-04-11_134107

Si se introduce nombre y contraseña de un usuario registrado, entonces se activa el botón que permitiría registrar equipos y en la barra de menú se activa la opción logout y se desactiva la de login (porque ahora ya hay un usuario logueado)

imagen_2021-04-11_134351

Así que en este estado el usuario podría registrar equipos. Y al cerrar sesión con logout, se volvería a desactivar el botón de registro hasta que se vuelva a loguear un usuario registrado.

Bien, vamos a ver el código que he usado. Como digo, es muy simple y básico, lo he escrito rápido a modo de ejemplo simplemente.

Primero una clase Usuario, poder registrarlos.
Uso el método equals() para comprobar rápidamente si dos usuarios son iguales. Esto luego me hará más fácil averiguar si los datos de usuario introducidos se corresponden con el de un usuario registrado.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Usuario {
 
	private String nombre;
	private String password;
 
	public Usuario(String nombre, String password) {
		this.nombre = nombre;
		this.password = password;
	}
 
	public String getNombre() {
		return nombre;
	}
 
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}
 
	public String getPassword() {
		return password;
	}
 
	public void setPassword(String password) {
		this.password = password;
	}
 
	@Override
	public boolean equals(Object user) {
		if (user instanceof Usuario) {
			Usuario otroUsuario = (Usuario) user;
			return (nombre.equals(otroUsuario.nombre) && password.equals(otroUsuario.password));
		}
		else
			return false;
	}
 
}

Ahora vamos a ver la clase del JDialog que pide los datos para validar Usuario.
Como dije, un JDialog es muy parecido a un JFrame, pero con la intención de usarlos de manera emergente como hacemos con los JOptionPane.

Este dialogo simplemente tiene dos campos de texto y un botón para validar datos.

En su constructor le pongo una referencia al ArrayList que contendrá los usuarios registrados para que esta clase pueda ver fácilmente esta lista de usuarios y comprobar si los datos introducidos se corresponden con alguno registrado.

También le paso por constructor el ActionListener que tendrá su botón. Este ActionListener lo escribiré en la clase principal del JFrame. Me interesa escribirlo ahí porque el resultado de la acción de este botón tendrá efectos en los componentes del JFrame, así que para poder interactuar con ellos, me es más cómodo escribir esta acción en el "ámbito" del JFrame y luego hacersela llegar al JDialog por su constructor.

Incluye un método boolean que se encarga de comprobar si los datos introducidos son válidos para loguear a un usuario.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public class DialogoLogin extends JDialog{
 
	private ArrayList<Usuario> usuarios;
	private JTextField jtNombre;
	private JTextField jtPass;
	private JButton btValidar;
 
	public DialogoLogin(Frame padre, boolean modal, ArrayList<Usuario> usuarios, ActionListener accionValidar) {
		super(padre, modal);
		this.usuarios = usuarios;
 
		jtNombre = new JTextField(8);
		jtPass = new JTextField(8);
		btValidar = new JButton("Validar datos");
		btValidar.addActionListener(accionValidar);
 
		JPanel pn1 = new JPanel();
		pn1.add(new JLabel("Introduzca los datos de usuario"));
		JPanel pn2 = new JPanel();
		pn2.setLayout(new FlowLayout(FlowLayout.RIGHT));
		pn2.add(new JLabel("Nombre: "));
		pn2.add(jtNombre);
		JPanel pn3 = new JPanel();
		pn3.setLayout(new FlowLayout(FlowLayout.RIGHT));
		pn3.add(new JLabel("Password: "));
		pn3.add(jtPass);
		JPanel pn4 = new JPanel();
		pn4.add(btValidar);
 
		JPanel pnPrincipal = new JPanel();
 
		pnPrincipal.setLayout(new BoxLayout(pnPrincipal, BoxLayout.Y_AXIS));
		pnPrincipal.add(pn1); pnPrincipal.add(pn2);
		pnPrincipal.add(pn3); pnPrincipal.add(pn4);
		pnPrincipal.setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 25));
 
		setContentPane(pnPrincipal);
 
		setTitle("Login");
		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		pack();
		setLocationRelativeTo(null);
	}
 
	public boolean validado() {
		//Recuperamos datos introducidos
		String nombre = jtNombre.getText();
		String pass = jtPass.getText();
		//Comprobamos que no esten vacíos.
		if (nombre.isBlank()) {
			JOptionPane.showMessageDialog(null, "Campo Nombre no puede estar vacío", "Validar datos",
					JOptionPane.WARNING_MESSAGE);
			return false;
		}
		else if (pass.isBlank()) {
			JOptionPane.showMessageDialog(null, "Campo Password no puede estar vacío", "Validar datos",
					JOptionPane.WARNING_MESSAGE);
			return false;
		}
		else {
			//comprobamos si existe un usuario con esos datos en el arraylist
			Usuario comprobar = new Usuario(nombre, pass);
			for (Usuario usu: usuarios) {
				if (usu.equals(comprobar))
					return true; //Usuario encontrado
			}
			//Si bucle for no ha retornado true, es que no hay usuario con esos datos
			JOptionPane.showMessageDialog(null, "No existe usuario con estos datos", "Validar datos",
					JOptionPane.INFORMATION_MESSAGE);
			return false;
		}
	}
 
}

Y por último, la clase principal que modela el JFrame.

Aquí es donde declaro como atributos un ArrayList de Usuarios, al que solo le añado uno para hacer pruebas.
Y los botones de la barra de menú y los botones grandes para crear usuarios y registrar equipos (repito, no les he dado ninguna función)

La clase JDialog para validar datos, también está declarada como un atributo del JFrame.

Además tiene tres subclases que son los ActionListener para los botones que si tendrán funcionalidades. Es aquí donde se decide la lógica del programa.
La acción de "login" lo que hace es construir el JDialog con lo que necesita y mostrarlo en pantalla.
La acción de "logout", desactiva el botón de registrar equipos.
La acción de "validar", es la que le pasamos al JDialog por constructor. Lo que hace es pedirle al JDialog que valide los datos que le haya dado el usuario y si son válidos, entonces activa el botón para poder registrar equipos y cierra el JDialog, pues ya ha cumplido su función.

Y eso es todo, fíjate que el método main (esta al final de la clase), no lleva a cabo ningún proceso de lógica. Simplemente llama al constructor del JFrame para que se ponga en marcha. Punto. Nada más. El resto de procesos lógicos se encargarán los botones de la interfaz.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
public class Login extends JFrame{
 
	private ArrayList<Usuario> usuarios;
	private DialogoLogin dlgLogin;
	private JMenuItem login;
	private JMenuItem logout;
	private JButton btCrearUser;
	private JButton btRegistrarEquipo;
 
	//Constructor JFrame
	public Login() {
 
		//Barra menu login
		JMenuBar barraMenu = new JMenuBar();
 
		JMenu acceso = new JMenu("Acceso Usuario");
		login = new JMenuItem("Login Usuario");
		login.addActionListener(new AccionLogin());
		logout = new JMenuItem("Logout Usuario");
		logout.addActionListener(new AccionLogout());
		logout.setEnabled(false);
		acceso.add(login);
		acceso.add(logout);
 
		barraMenu.add(acceso);
		setJMenuBar(barraMenu);
 
		//Usuarios
		usuarios = new ArrayList<Usuario>();
		usuarios.add(new Usuario("admin", "admin"));//Usuario de prueba
 
		//controles interfaz
		btCrearUser = new JButton("<html><p style=text-align:\"center\">Crear<br>Usuario</p></html>");
		btCrearUser.setFont(new Font("Verdana", Font.BOLD, 24));
		btRegistrarEquipo = new JButton("<html><p  style=text-align:\"center\">Registrar<br>Equipo</p></html>");
		btRegistrarEquipo.setFont(new Font("Verdana", Font.BOLD, 24));
		btRegistrarEquipo.setEnabled(false);
 
		//Maquetación
		JPanel pnCrear = new JPanel();
		pnCrear.add(btCrearUser);
		pnCrear.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createEmptyBorder(40, 40, 40, 40),
				BorderFactory.createRaisedSoftBevelBorder()));
		JPanel pnRegistrar = new JPanel();
		pnRegistrar.add(btRegistrarEquipo);
		pnRegistrar.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createEmptyBorder(40, 40, 40, 40),
				BorderFactory.createRaisedSoftBevelBorder()));
 
		setLayout(new FlowLayout());
		add(pnCrear);
		add(pnRegistrar);
 
		//Configuracion JFrame
		setTitle("Ejemplo Login");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		pack();
		setLocationRelativeTo(null);
		setVisible(true);
	}
 
	//Acciones
	private class AccionLogin implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			//Mostramos dialogo para login
			dlgLogin = new DialogoLogin(null, true, usuarios, new AccionValidar());
			dlgLogin.setVisible(true);
		}
	}
 
	private class AccionLogout implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			//Desactivamos boton de registro y de login
			btRegistrarEquipo.setEnabled(false);
			login.setEnabled(true);
			logout.setEnabled(false);
		}
	}
 
	private class AccionValidar implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			/*
			 * Esta accion hace que el JDialog compruebe
			 * si los datos introducidos son validos para
			 * efectuar un login de usuario.
			 * En caso afirmativo, se activará el botón
			 * de registrar equipos y la función de logout.
			 * Y se cerrará el JDialog
			 */
			if (dlgLogin.validado()) {
				btRegistrarEquipo.setEnabled(true);
				logout.setEnabled(true);
				login.setEnabled(false);
				dlgLogin.dispose();
			}
 
		}
	}
 
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				new Login(); //Se pone en marcha el JFrame
			}
		});
	}
}

Llegados aquí, ¿Cómo se podría hacer lo de registrar equipos?
Pues se podría escribir otro JDialog, por ejemplo.

O se podría hacer que el JFrame contuviera distintos paneles en un CardLayout y con botones poder escoger entre el panel que se encarga de crear usuarios, el que se encarga de registrar equipos, el que se encarga de listar los equipos creados, etc...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar
sin imagen de perfil
Val: 40
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Parar main mientras se ejecuta un JFram

Publicado por Fran (13 intervenciones) el 12/04/2021 10:40:52
Grandiosa explicación!!

Muchas gracias!!

Ahora lo pondrá en marcha y ya te contaré qué tal fue todo?

Un saludo!!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar