Autor Tema: proyecto Ticket enumeraciones clase abstracta final recursiva Swing #codigoJava  (Leído 7091 veces)

Demo8v

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 12
    • Ver Perfil
Hola, necesitaría ayuda con este proyecto, agradezco cualquier aportación.

El proyecto consiste en un sistema llamada JAVA TICKET en el cual ofrece boletos para eventos deportivos, musicales o religiosos dentro de un estadio. El sistema también distingue entre varios usuarios como Usuario ADMINISTRADOR, usuario de CONTENIDOS y usuario LIMITADO. Tanto los eventos como los usuarios se manejarán con herencia.

El proyecto tiene las siguientes opciones:


PARTE LOGIN

El programa debe mostrar al inicio un login. En el cual se pide el usuario y el password. Si es un usuario valido se deja entrar al sistema, de lo contrario se muestra un mensaje de error. DE INICIO existe un usuario ADMINISTRADOR con el user admin y el password supersecreto.


PARTE SISTEMA

Se muestra el MENU PRINCIPAL del programa el cual consta de las siguientes opciones. Estar atentos a que varias opciones NO están disponibles para algunos usuarios:

1 – ADMINISTRACION DE EVENTOS


Dentro de esta opción se encuentra un submenú que consta de las siguientes opciones

1. Crear un evento. En esta opción el usuario selecciona primero si el evento es deportivo, musical o religioso. Cada evento tiene cosas en común como un código único, titulo del evento, una descripción de este, la fecha en la que se realizara el evento y el monto acordado de renta del estadio; todas estas se ingresan del teclado.
Luego por evento tienen cosas extras que se consideran:

DEPORTIVO = LA CANTIDAD MAXIMA de gente permitida es de 20 mil. Tiene 2 atributos que se ingresaran para detallar el nombre de los 2 equipos y otro que me diga el
tipo de deporte que se usara una enumeración y sus opciones son: (FUTBOL, TENIS,
RUGBY o BASEBALL). Estos datos se ingresan aquí en la creación, vea la parte de editar para datos extras que tiene un evento deportivo.

MUSICAL = LA CANTIDAD MAXIMA permitida es de 25 mil (por el uso de la grama).
Se ingresa el tipo de música a interpretar que se obtiene de una enumeración con las
opciones POP, ROCK, RAP, CLASICA, REGGEATON, OTRO. Se le cobra un seguro
por la grama de 30% sobre el valor acordado de renta. Ver edición para cosas extras de eventos musicales.

RELIGIOSO = LA CANTIDAD MAXIMA permitida es de 30 mil. Se cobra 2000 lps
fijos de seguro por el desgaste de la grama.

=== SOLO EL USUARIO LIMITADO NO ESTA PERMITIDO CREAR EVENTOS ===

2. Eliminar un evento. Se pide que se ingrese el código del evento. Si ese evento existe Y NO SE HA REALIZADO AUN, se procede a marcarlo como cancelado. SOLO que si la fecha es apenas 1 dia antes de su realización se cobrara el 50% del monto acordado como indemnización a excepción de las religiosas que NO PAGAN NADA.
=== SOLO EL USUARIO QUE CREO EL EVENTO PUEDE BORRAR DICHO EVENTO ===

3. Editar un evento. Se pide que se ingrese el código, si el evento existe se procede a editarlo, no importa que el evento ya se realizo. Se puede editar todos los datos que se ingresaron al momento de la creación además de cosas extras que cada evento tiene, como ser:

DEPORTIVO=Se puede ingresar el listado de jugadores por cada equipo. Cada uno en un ArrayList que contiene sus nombres.

MUSICAL=Se puede ingresar en un ArrayList el nombre de todas las personas que
conforman el equipo que monta todo el show musical.

RELIGIOSO=Por petición de la iglesia se puede dejar guardado la cantidad de personas convertidas esa noche.

=== SOLO EL USUARIO LIMITADO NO ESTA PERMITIDO CREAR EVENTOS===

4. Ver evento. Se pide que se ingrese el código, SI EXISTE, se imprime TODOS LOS
DATOS que dicho evento tiene, además del tipo de este. También se muestra un mensaje por si el evento ha sido cancelado y su multa pagada.
=== DISPONIBLE PARA TODOS LOS USUARIO ===

5. Regresar al menú principal. Ya que al finalizar cada operación en este submenú se
mantiene en este menú. Hasta que se selecciona esta opción se regresa al menú principal.


2- ADMINISTRACION DE USUARIOS

Esta opción SOLO ESTA DISPONIBLE PARA LOS USUARIOS ADMINISTRADORES.

Tiene un submenú para poder CREAR, EDITAR o BORRAR un usuario. Cada usuario consta de los siguientes datos en común:

a. Nombre completo
b. Username (valor UNICO utilizado en el login)
c. Password
d. Edad

NOTA= Antes de crear un usuario se pide de que tipo es, de esa forma poder inicializarlos. Los usuarios ADMINISTRATIVOS y de CONTENIDOS poseen un ArrayList para guardar los ids de los eventos que ellos han creado (Estos ids se agregan al momento de la creación del evento).

3- REPORTES

Contiene el siguiente submenú:

a. Listar eventos realizados. Lista el CODIGO – TIPO - TITULO – FECHA – MONTO de
cada evento ya realizado. Al final se muestra un detalle estadístico de cuantos fueron
DEPORTIVOS, cuantos RELIGIOSOS y cuantos MUSICALES al igual que el monto total
generado por cada uno de ellos. Se muestra del más reciente al más viejo.

b. Listar eventos futuros. Lista el CODIGO – TIPO - TITULO – FECHA – MONTO de cada
evento QUE NO SE HA REALIZADO AÚN. Al final se muestra un detalle estadístico de
cuantos son DEPORTIVOS, cuantos RELIGIOSOS y cuantos MUSICALES al igual que
el monto total que estos generaran por cada uno de estos tipos.

c. Listar eventos cancelados. Lista el CODIGO – TIPO - TITULO – FECHA – MULTA de
cada evento QUE SE CANCELO. Al final se muestra un detalle estadístico de cuantos son DEPORTIVOS, cuantos RELIGIOSOS y cuantos MUSICALES. Y el total en MULTA
por indemnización.

d. Ingreso generado por fecha. Se pide una fecha inicial y una fecha final. Y se muestra el total generado (incluso con eventos que no han pasado) entre todos los eventos. También aquí se incluye las multas por cancelaciones. Se muestra un detalle de cuántos de estos eventos filtrados son DEPORTIVOS, cuantos RELIGIOSOS y cuantos MUSICALES.

e. Ver Perfil del usuario. Muestra TODA LA INFORMACION del usuario que esta “logged
in” en la aplicación. Además de un listado con todos los eventos que ha creado con el
formato ID – TIPO – TITULO – MONTO.

f. Regresar a Menú Principal.

4- SALIR

El programa termina.


REQUISITOS:


• TRABAJAR CON HERENCIA PARA EL MANEJO DE LOS USUARIOS Y EVENTOS.
• USO DE ENUMERACIONES.
• DEBE TENER POR LO MENOS 1 CLASE ABSTRACTA, 1 CLASE FINAL, > 1 ATRIBUTOS Y FUNCIONES FINALES.
• DEBE TENER POR LO MENOS 3 FUNCIONES RECURSIVAS.
• USAR EL PROYECTO EN LA LIBRERIA SWING.
« Última modificación: 17 de Abril 2022, 19:04 por Alex Rodríguez »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 983
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #1 en: 16 de Febrero 2021, 01:15 »
Hola.
Este mensaje me había pasado desapercibido.
¿Tienes algo hecho ya?

Se podría empezar por las clases de usuarios que participan:

Clase Usuario(abstracta):
Código: [Seleccionar]
/**
 * Clase abstracta con los atributos y métodos comunes
 * a todos los tipos de usuarios que existirán en el programa.<br>
 * Incluye método <i>equals()</i> sobreescrito de manera que
 * dos objetos Usuario son equivalentes si coincide el atributo
 * <i>userName</i>, el cuál se considera como un identificador
 * de usuarios <u>único</u>.
 */
public abstract class Usuario {

private String nombre;
private String userName;
private String password;
private int edad;

public Usuario(String nombre, String userName, String password, int edad) {
this.nombre = nombre;
this.userName = userName;
this.password = password;
this.edad = edad;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public int getEdad() {
return edad;
}

public void setEdad(int edad) {
this.edad = edad;
}

/**
* Dos usuarios son iguales si tienen el
* mismo nombre de usuario, es decir,
* coincide el atributo <i>userName</i>
*/
@Override
public boolean equals(Object obj) {
if (obj instanceof Usuario) {
Usuario otroUser = (Usuario)obj;
return otroUser.userName.equals(userName);
}
else
return false;
}

}

Clase Administrador
Código: [Seleccionar]
import java.util.ArrayList;

import javax.swing.JOptionPane;

/**
 * Modela un Usuario de tipo Administrador, el cuál tendrá
 * poder total dentro del programa.<br>Podrá crear eventos y también
 * crear otros usuarios.
 */
public final class Administrador extends Usuario {

private ArrayList<String> idEventos;

public Administrador(String nombre, String userName, String password, int edad) {
super(nombre, userName, password, edad);
idEventos = new ArrayList<String>();
}

/**
* Agrega el id de un evento al registro
* de eventos creados por este usuario.
* @param id Identificador del evento
*/
public void agregarIdEvento(String id) {
idEventos.add(id);
}

/**
* Elimina el id de un evento del registro
* de eventos creados por este usuario.<br>
* Si el id no consta en el registro, se mostrará
* un mensaje emergente de advertencia.
* @param id Identificador del evento
*/
public void eliminaIdEvento(String id) {
if (esCreadorDeEvento(id))
idEventos.remove(id);
else
JOptionPane.showMessageDialog(null, "Este evento no ha sido creador por este usuario",
"Eliminar Evento", JOptionPane.WARNING_MESSAGE);
}

/**
* Comprueba si un determinado evento es
* creación de este usuario.<br>
* Para ello se comprueba la existencia del ID del evento
* en el ArrayList que registra los eventos creados por este usuario.
* @param id Identificador del evento.
* @return TRUE si el evento ha sido creado por este usuario,
* FALSE en caso contrario.
*/
public boolean esCreadorDeEvento(String id) {
return idEventos.contains(id);
}
}

Clase DeContenidos:
Código: [Seleccionar]
import java.util.ArrayList;

import javax.swing.JOptionPane;

/**
 * Modela un Usuario de tipo "De contenidos".<br>
 * Este usuario podrá crear eventos, pero no podrá
 * crear otros usuarios.
 */
public final class DeContenidos extends Usuario{

private ArrayList<String> idEventos;

public DeContenidos(String nombre, String userName, String password, int edad) {
super(nombre, userName, password, edad);
idEventos = new ArrayList<String>();
}

/**
* Agrega el id de un evento al registro
* de eventos creados por este usuario.
* @param id Identificador del evento
*/
public void agregarIdEvento(String id) {
idEventos.add(id);
}

/**
* Elimina el id de un evento del registro
* de eventos creados por este usuario.<br>
* Si el id no consta en el registro, se mostrará
* un mensaje emergente de advertencia.
* @param id Identificador del evento
*/
public void eliminaIdEvento(String id) {
if (esCreadorDeEvento(id))
idEventos.remove(id);
else
JOptionPane.showMessageDialog(null, "Este evento no ha sido creador por este usuario",
"Eliminar Evento", JOptionPane.WARNING_MESSAGE);
}

/**
* Comprueba si un determinado evento es
* creación de este usuario.<br>
* Para ello se comprueba la existencia del ID del evento
* en el ArrayList que registra los eventos creados por este usuario.
* @param id Identificador del evento.
* @return TRUE si el evento ha sido creado por este usuario,
* FALSE en caso contrario.
*/
public boolean esCreadorDeEvento(String id) {
return idEventos.contains(id);
}

}

Clase Limitado:
Código: [Seleccionar]
/**
 * Modela un Usuario de tipo Limitado.<br>
 * Este usuario no podrá crear eventos ni otros usuarios.
 */

public final class Limitado extends Usuario{

public Limitado(String nombre, String userName, String password, int edad) {
super(nombre, userName, password, edad);
}

}
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Demo8v

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 12
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #2 en: 16 de Febrero 2021, 05:21 »
Hola, Muchas gracias por responder. Por los momentos lo que tengo es la interfaz gráfica y un poco del login; digo un poco por que aun faltan algunos detalles para distinguir y almacenar los usuario. También (ya que es mi primera vez trabajando con la librería swing) tomé prestado un código tuyo de trabajos pasados para intentar adaptarlo a mi proyecto y hasta el momento solo estoy creando los diferentes paneles. Te adjuntare por partes lo que tengo ya que tengo limite de carga.

Ahora mismo procederé a ver como implemento lo que me has dejado, muchas gracias, en serio tengo que entregar esto a mas tardar el jueves  :'(

Nota: código en archivos adjuntos. Es necesario estar logado para descargar los archivos.
« Última modificación: 17 de Abril 2022, 18:47 por Alex Rodríguez »

Demo8v

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 12
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #3 en: 16 de Febrero 2021, 05:23 »
Los poco que tengo de usuarios, hay algunas funciones del código copiado.

Nota: código en archivos adjuntos. Es necesario estar logado para descargar los archivos.

« Última modificación: 17 de Abril 2022, 18:48 por Alex Rodríguez »

Demo8v

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 12
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #4 en: 16 de Febrero 2021, 05:26 »
Y por último esto, no te adjunto la clase PanelBorrar por que aun está incompleta.

Nota: código en archivos adjuntos. Es necesario estar logado para descargar los archivos.

« Última modificación: 17 de Abril 2022, 18:48 por Alex Rodríguez »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 983
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #5 en: 16 de Febrero 2021, 12:29 »
Bufff... pues andas mal de tiempo.

Y cuidado con reaprovechar código de otros programas, a veces se tarda más intentando componer esas "piezas" para adaptarlas a tu programa, que escribirlas de cero.
Pueden servir de inspiración, pero no siempre se pueden copiar y usar directamente.

Por otro lado, es importante tener las clases principales más o menos ya establecidas, para luego tener claro que necesitamos pedir y hacer en la parte de la interfaz gráfica.

Las clases de Eventos podrían ser estas:

Clase Evento (abstracta)
Código: [Seleccionar]
/**
 * Clase abstracta con todos los atributos y métodos comunes
 * a todos los tipos de eventos que existirán en el programa.<br>
 * Incluye método <i>equals()</i> sobreescrito de manera que
 * dos objetos Evento son equivalentes si coincide el atributo
 * <i>codigo</i>, el cuál se considera como un identificador
 * de eventos <u>único</u>.
 */
public abstract class Evento {

private String codigo;
private String titulo;
private String descripcion;
private String fecha;
protected double renta; //Protected porque algunas clases hijas necesitan verla para calcular seguro

public Evento(String codigo, String titulo, String descripcion, String fecha, double renta) {
this.codigo = codigo;
this.titulo = titulo;
this.descripcion = descripcion;
this.fecha = fecha;
this.renta = renta;
}

public String getCodigo() {
return codigo;
}

public void setCodigo(String codigo) {
this.codigo = codigo;
}

public String getTitulo() {
return titulo;
}

public void setTitulo(String titulo) {
this.titulo = titulo;
}

public String getDescripcion() {
return descripcion;
}

public void setDescripcion(String descripcion) {
this.descripcion = descripcion;
}

public String getFecha() {
return fecha;
}

public void setFecha(String fecha) {
this.fecha = fecha;
}

public double getRenta() {
return renta;
}

public void setRenta(double renta) {
this.renta = renta;
}

@Override
public boolean equals(Object obj) {

if (obj instanceof Evento) {
Evento otroEvento = (Evento)obj;
return otroEvento.codigo.equals(codigo);
}
else
return false;
}

}

Clase Deportivo
Código: [Seleccionar]
import javax.swing.JOptionPane;

/**
 * Modela un Evento de tipo Deportivo.<br>
 * Este evento tiene un aforo máximo de 20000
 */
public final class Deportivo extends Evento{

//Constante que establece el limite de personas que pueden asistir a este evento
private final int AFORO_MAXIMO = 20000;
//Atributos
private int aforo;
private String equipo1;
private String equipo2;
private TipoDeporte tipoDeporte;

public Deportivo(String codigo, String titulo, String descripcion, String fecha, double renta,
int aforo, String equipo1, String equipo2, TipoDeporte tipoDeporte) {
super(codigo, titulo, descripcion, fecha, renta);

setAforo(aforo);
this.equipo1 = equipo1;
this.equipo2 = equipo2;
this.tipoDeporte = tipoDeporte;
}

public int getAforo() {
return aforo;
}

/**
* Establece la cantidad de gente que asistirá al evento.<br>
* Esta cantidad está limitada por la constante <i>AFORO_MAXIMO.</i>
* @param aforo Cantidad de gente que asistirá al evento.
*/
public void setAforo(int aforo) {
if (aforo > AFORO_MAXIMO) {
JOptionPane.showMessageDialog(null, "El aforo indicado supera el límite establecido."
+ "El aforo será establecido a " + AFORO_MAXIMO, "Crear Evento Derportivo",
JOptionPane.WARNING_MESSAGE);
this.aforo = AFORO_MAXIMO;
}
else
this.aforo = aforo;
}

public String getEquipo1() {
return equipo1;
}

public void setEquipo1(String equipo1) {
this.equipo1 = equipo1;
}

public String getEquipo2() {
return equipo2;
}

public void setEquipo2(String equipo2) {
this.equipo2 = equipo2;
}

public TipoDeporte getTipoDeporte() {
return tipoDeporte;
}

public void setTipoDeporte(TipoDeporte tipoDeporte) {
this.tipoDeporte = tipoDeporte;
}

}

Clase Musical
Código: [Seleccionar]
import javax.swing.JOptionPane;

/**
 * Modela un Evento de tipo Musical<br>
 * Este evento tiene un aforo máximo de 25000 personas.
 */
public final class Musical extends Evento{

//Constante que establece el limite de personas que pueden asistir a este evento
private final int AFORO_MAXIMO = 25000;
//Constante que establece el % de cuota de seguro que se cobra sobre la renta acordada
private final double CUOTA_SEGURO = 30d; //30%
//Atributos
private int aforo;
private TipoMusica tipoMusica;

public Musical(String codigo, String titulo, String descripcion, String fecha, double renta,
int aforo, TipoMusica tipoMusica) {
super(codigo, titulo, descripcion, fecha, renta);
setAforo(aforo);
this.tipoMusica = tipoMusica;
}

public int getAforo() {
return aforo;
}

/**
* Establece la cantidad de gente que asistirá al evento.<br>
* Esta cantidad está limitada por la constante <i>AFORO_MAXIMO.</i>
* @param aforo Cantidad de gente que asistirá al evento.
*/
public void setAforo(int aforo) {
if (aforo > AFORO_MAXIMO) {
JOptionPane.showMessageDialog(null, "El aforo indicado supera el límite establecido."
+ "El aforo será establecido a " + AFORO_MAXIMO, "Crear Evento Derportivo",
JOptionPane.WARNING_MESSAGE);
this.aforo = AFORO_MAXIMO;
}
else
this.aforo = aforo;
}

public TipoMusica getTipoMusica() {
return tipoMusica;
}

public void setTipoMusica(TipoMusica tipoMusica) {
this.tipoMusica = tipoMusica;
}

/**
* Establece el importe del seguro que se cobra
* por el uso de la grama.<br>Este importe es el
* 30% del valor de la renta acordada.
* @return Importe del seguro.
*/
public double getImporteSeguro() {
return  renta * CUOTA_SEGURO / 100;
}

}

Clase Religioso
Código: [Seleccionar]
import javax.swing.JOptionPane;

/**
 * Modela un Evento de tipo Religioso.<br>
 * Este evento tiene un aforo maximo de 30000 personas.
 */
public final class Religioso extends Evento{

//Constante que establece el limite de personas que pueden asistir a este evento
private final int AFORO_MAXIMO = 30000;
//Constante que establece el importe fijado como seguro por desgaste de la grama
public final int CUOTA_SEGURO = 2000; //Public, no será necesario usar getter para acceder a este valor
//Atributos
private int aforo;

public Religioso(String codigo, String titulo, String descripcion, String fecha, double renta,
int aforo) {
super(codigo, titulo, descripcion, fecha, renta);
setAforo(aforo);
}

public int getAforo() {
return aforo;
}

/**
* Establece la cantidad de gente que asistirá al evento.<br>
* Esta cantidad está limitada por la constante <i>AFORO_MAXIMO.</i>
* @param aforo Cantidad de gente que asistirá al evento.
*/
public void setAforo(int aforo) {
if (aforo > AFORO_MAXIMO) {
JOptionPane.showMessageDialog(null, "El aforo indicado supera el límite establecido."
+ "El aforo será establecido a " + AFORO_MAXIMO, "Crear Evento Derportivo",
JOptionPane.WARNING_MESSAGE);
this.aforo = AFORO_MAXIMO;
}
else
this.aforo = aforo;
}

}

Y se usarían estos dos enumerados:

Código: [Seleccionar]
public enum TipoDeporte {
FUTBOL, TENIS, RUGBY, BASEBALL
}

Código: [Seleccionar]
public enum TipoMusica {
POP, ROCK, RAP, CLASICA, REGGEATON, OTRO
}
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Demo8v

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 12
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #6 en: 16 de Febrero 2021, 17:32 »
Gracias por tu apoyo! Y tienes razón, reaprovechar el código hizo atrasarme un poco, pero por ahora solo estoy usando la parte de interfaz grafica sin funciones (además de volver, salir, cerrar programa, etc.) Hago esto por el poco tiempo que tengo, estuve enfermo mucho tiempo y ahora estoy entre la espada y la pared, pero creo que lograré terminar casi en su totalidad antes del jueves, o eso espero. En verdad te agradecería si me ayudaras a terminarlo antes del jueves, aunque sino no te preocupes, se que mis necesidades no son tus problemas jaja

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 983
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #7 en: 17 de Febrero 2021, 03:18 »
La cosa es que yo tampoco dispongo de apenas tiempo, y un programa como este, requiere tiempo...
He hecho algunos avances más.

El programa inicia con pantalla de login:



Si el login es correcto, accedemos al panel principal:



Pero no funciona nada todavía, excepto el botón de salir.

Si se cancela la ventana de login, el panel principal aparece pero desactivado.



La idea sería añadir un barra de menu superior que permita login/logout sin tener que reabrir la aplicación, pero eso ya sería dejarlo para lo último, ante la falta de tiempo.

Para controlar los Usuarios registrados y el tema del login, uso una clase dedicada a eso, a gestionar usuarios:
Código: [Seleccionar]
import java.util.ArrayList;

import javax.swing.JOptionPane;

public class GestorUsuarios {

private ArrayList<Usuario> usuarios;

public GestorUsuarios() {
usuarios = new ArrayList<Usuario>();
usuarios.add(new Administrador("Administrador", "admin", "supersecreto", 0));
}

public boolean agregarUsuario(Usuario usuario) {
if (usuarios.contains(usuario)) {
JOptionPane.showMessageDialog(null, "Este usuario ya está registrado",
"Registrar nuevo Usuario", JOptionPane.WARNING_MESSAGE);
return false;
}
else
return usuarios.add(usuario);
}

public Usuario loginUsuario(String userName, String password) {

for (Usuario user: usuarios) {
if (user.getUserName().equals(userName)) {
if (user.getPassword().equals(password))
return user; //Usuario encontrado, lo retornamos para login
else { //Contraseña incorrecta
JOptionPane.showMessageDialog(null, "La contraseña no es correcta",
"Login Usuario", JOptionPane.WARNING_MESSAGE);
return null;
}

}
}
//Finalizado el for sin retornar nada, es que no existe ese username
JOptionPane.showMessageDialog(null, "Nombre de Usuario no existe",
"Login Usuario", JOptionPane.WARNING_MESSAGE);
return null;
}

}

La ventana de login, es un JDialog:
Código: [Seleccionar]
public class DialogoLogin extends JDialog {

private JTextField campoNombre;
private JPasswordField campoPass;
private JButton btEnviar;
private GestorUsuarios gestorUsuarios;
private Font fuente;

public DialogoLogin(Frame padre, boolean modal, GestorUsuarios gestor) {
super(padre, modal);
gestorUsuarios = gestor;
fuente = new Font("Verdana", Font.PLAIN, 20);

JPanel centro = new JPanel();
centro.setLayout(new BoxLayout(centro, BoxLayout.Y_AXIS));
centro.add(new PanelNombre());
centro.add(new PanelPass());
centro.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(20, 25, 20, 25),
BorderFactory.createLoweredSoftBevelBorder()));

setLayout(new BorderLayout());
add(new PanelImagen(), BorderLayout.NORTH);
add(centro, BorderLayout.CENTER);
add(new PanelEnviar(), BorderLayout.SOUTH);

setTitle("Login Usuario");
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
pack();
setResizable(false);
setLocationRelativeTo(null);
}

private class PanelImagen extends JPanel {

public PanelImagen() {
ImageIcon imagen = new ImageIcon(DialogoLogin.class.getClassLoader().getResource("img/login.png"));
JLabel icono = new JLabel(imagen);
icono.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
add(icono);
}
}

private class PanelNombre extends JPanel {

public PanelNombre() {
campoNombre = new JTextField(10);
campoNombre.setFont(fuente);
JLabel etiq = new JLabel("Nombre de Usuario: ");
etiq.setFont(fuente);
setLayout(new FlowLayout(FlowLayout.RIGHT));
add(etiq);
add(campoNombre);
}
}

private class PanelPass extends JPanel {

public PanelPass() {
campoPass = new JPasswordField(10);
campoPass.setFont(fuente);
JLabel etiq = new JLabel("Contraseña: ");
etiq.setFont(fuente);
setLayout(new FlowLayout(FlowLayout.RIGHT));
add(etiq);
add(campoPass);
}
}

private class PanelEnviar extends JPanel {

public PanelEnviar() {
btEnviar = new JButton("Enviar");
btEnviar.setFont(new Font("Verdana", Font.BOLD, 24));
add(btEnviar);
}
}

public Usuario getUsuarioLogin() {
String userName = campoNombre.getText();
String password = String.valueOf(campoPass.getPassword());
if (userName == null || userName.isBlank() || userName.isEmpty()) {
java.awt.Toolkit.getDefaultToolkit().beep();
return null;
}

return gestorUsuarios.loginUsuario(userName, password);
}

public void setAccionEnviar(ActionListener accion) {
btEnviar.addActionListener(accion);
}

}

El panel principal es un JPanel con los 4 botones.
Uno de los métodos es para decidir si se activa o no el botón de administrar usuarios, dependiendo de si el usuario logueado es administrador o no.

Código: [Seleccionar]
public class PanelPrincipal extends JPanel{

private JButton btEventos;
private JButton btUsuarios;
private JButton btReportes;
private JButton btSalir;
private JLabel bienvenido;

public PanelPrincipal() {
iniciarBotones();
bienvenido = new JLabel("No hay usuario logueado");

setLayout(new BorderLayout());
add(new PanelSaludo(), BorderLayout.NORTH);

JPanel pnCentro = new JPanel();
pnCentro.setLayout(new GridLayout(2, 2, 10, 10));
pnCentro.add(new PanelBoton(btEventos, "Administrar Eventos"));
pnCentro.add(new PanelBoton(btUsuarios, "Administrar Usuarios"));
pnCentro.add(new PanelBoton(btReportes, "Mostrar Reportes"));
pnCentro.add(new PanelBoton(btSalir, "Cerrar Aplicación"));
pnCentro.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

add(pnCentro, BorderLayout.CENTER);

}

private void iniciarBotones() {
btEventos = new JButton();
btEventos.setIcon(
new ImageIcon(PanelPrincipal.class.getClassLoader().getResource("img/administrarEvento.png")));
btEventos.setEnabled(false);
btEventos.setFocusPainted(false);

btUsuarios = new JButton();
btUsuarios.setIcon(
new ImageIcon(PanelPrincipal.class.getClassLoader().getResource("img/administrarUsuario.png")));
btUsuarios.setEnabled(false);
btUsuarios.setFocusPainted(false);

btReportes = new JButton();
btReportes.setIcon(
new ImageIcon(PanelPrincipal.class.getClassLoader().getResource("img/reportes.png")));
btReportes.setEnabled(false);
btReportes.setFocusPainted(false);

btSalir = new JButton();
btSalir.setIcon(
new ImageIcon(PanelPrincipal.class.getClassLoader().getResource("img/salir.png")));
btSalir.setFocusPainted(false);
btSalir.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int respuesta = JOptionPane.showConfirmDialog(null, "¿Cerrar Aplicacion?",
"Cerrar Programa", JOptionPane.YES_NO_OPTION);
if (respuesta == JOptionPane.YES_OPTION)
System.exit(0);
}
});
}

public void setSaludo(String saludo) {
bienvenido.setText(saludo);
}

public void activarPanel(boolean esAdmin) {
btUsuarios.setEnabled(esAdmin);
btEventos.setEnabled(true);
btReportes.setEnabled(true);
}

private class PanelSaludo extends JPanel {

public PanelSaludo() {
bienvenido.setFont(new Font("Verdana", Font.ITALIC, 32));
JPanel pnBienvenido = new JPanel();
pnBienvenido.add(bienvenido);
pnBienvenido.setBorder(BorderFactory.createLoweredSoftBevelBorder());
add(pnBienvenido);
}
}

private class PanelBoton extends JPanel {

public PanelBoton(JButton boton, String texto) {
setLayout(new BorderLayout());
add(boton, BorderLayout.CENTER);
JLabel etTexto = new JLabel(texto);
etTexto.setFont(new Font("Verdana", Font.BOLD ,18));
JPanel pnTexto = new JPanel();
pnTexto.add(etTexto);
add(pnTexto, BorderLayout.SOUTH);
setBorder(
BorderFactory.createCompoundBorder(BorderFactory.createRaisedSoftBevelBorder(),
BorderFactory.createEmptyBorder(15, 15, 15, 15)));
}
}

}

La clase principal, la que modela el JFrame, tendrá todos los paneles que se vayan creando más adelante y se irían mostrando mediante un CardLayout, igual que en el ejemplo que encontraste.
También tendrá los objetos propios del "modelo".

De momento lo que hace es inicializar todos estos objetos y mostrar el dialogo de login.
Si se cancela, muestra panel principal desactivado.
Si el login funciona, muestra el panel adecuado según el tipo de usuario.

Código: [Seleccionar]
public final class JavaTicket extends JFrame{

//Partes del MODELO
private GestorUsuarios gestorUsuarios;
private Usuario usuarioLogueado;

//Partes de la VISTA
private DialogoLogin dialogoLogin;
private PanelPrincipal pnPrincipal;
private CardLayout cardLayout;
private JPanel panelActivo;

public JavaTicket() {

iniciarModelo();
iniciarVista();

add(panelActivo);

setTitle("Java Ticket");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}

private void iniciarModelo() {
gestorUsuarios = new GestorUsuarios();
usuarioLogueado = null;
}

private void iniciarVista() {

pnPrincipal = new PanelPrincipal();
cardLayout = new CardLayout();
panelActivo = new JPanel();
panelActivo.setLayout(cardLayout);
panelActivo.add(pnPrincipal, "principal");
dialogoLogin = new DialogoLogin(this, true, gestorUsuarios);
dialogoLogin.setAccionEnviar(new AccionEnviarLogin());
dialogoLogin.setVisible(true);
}

private class AccionEnviarLogin implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
usuarioLogueado = dialogoLogin.getUsuarioLogin();

if (usuarioLogueado != null) {
pnPrincipal.setSaludo("Bienvenido " + usuarioLogueado.getNombre());
String clase = usuarioLogueado.getClass().getName();
switch(clase) {
case "usuarios.Administrador":
pnPrincipal.activarPanel(true);
break;
case "usuarios.DeContenidos":
pnPrincipal.activarPanel(false);
break;
case "usuarios.Limitado":
pnPrincipal.activarPanel(false);
break;
}

dialogoLogin.setVisible(false);
}
}
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new JavaTicket();
}
});
}

}

Dejo un enlace a Google Drive para descargar un zip con todo el proyecto, incluidas las imágenes que he usado. (aunque se pueden usar las que uno quiera, o no usar ninguna)

Mañana intentaré hacer algo más

NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 983
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #8 en: 17 de Febrero 2021, 12:02 »
Pequeña actualización.

Añado nuevo panel para la gestión de usuarios, de momento sin funcionalidad, excepto para el botón "volver"



Esta es la clase para este panel de usuarios. Es prácticamente calcada a la clase del panel principal.

Código: [Seleccionar]
public class PanelUsuarios extends JPanel{

private JButton btNuevo;
private JButton btModificar;
private JButton btEliminar;
private JButton btVolver;

public PanelUsuarios() {

iniciarBotones();

setLayout(new BorderLayout());
add(new PanelTitulo(), BorderLayout.NORTH);

JPanel pnCentro = new JPanel();
pnCentro.setLayout(new GridLayout(2, 2, 10, 10));
pnCentro.add(new PanelBoton(btNuevo, "Crear Usuario"));
pnCentro.add(new PanelBoton(btModificar, "Modificar Usuario"));
pnCentro.add(new PanelBoton(btEliminar, "Eliminar Usuario"));
pnCentro.add(new PanelBoton(btVolver, "Volver a menú principal"));
pnCentro.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

add(pnCentro, BorderLayout.CENTER);
}

private void iniciarBotones() {
btNuevo = new JButton();
btNuevo.setIcon(
new ImageIcon(PanelPrincipal.class.getClassLoader().getResource("img/crearUsuario.png")));
btNuevo.setFocusPainted(false);

btModificar = new JButton();
btModificar.setIcon(
new ImageIcon(PanelPrincipal.class.getClassLoader().getResource("img/editarUsuario.png")));
btModificar.setFocusPainted(false);

btEliminar = new JButton();
btEliminar.setIcon(
new ImageIcon(PanelPrincipal.class.getClassLoader().getResource("img/borrarUsuario.png")));
btEliminar.setFocusPainted(false);

btVolver = new JButton();
btVolver.setIcon(
new ImageIcon(PanelPrincipal.class.getClassLoader().getResource("img/volver.png")));
}

public void setAccionVolver(ActionListener accion) {
btVolver.addActionListener(accion);
}


private class PanelTitulo extends JPanel {

public PanelTitulo() {
JLabel titulo = new JLabel("Administrar Usuarios");
titulo.setFont(new Font("Verdana", Font.ITALIC, 32));
JPanel pnBienvenido = new JPanel();
pnBienvenido.add(titulo);
pnBienvenido.setBorder(BorderFactory.createLoweredSoftBevelBorder());
add(pnBienvenido);
}
}


private class PanelBoton extends JPanel {

public PanelBoton(JButton boton, String texto) {
setLayout(new BorderLayout());
add(boton, BorderLayout.CENTER);
JLabel etTexto = new JLabel(texto);
etTexto.setFont(new Font("Verdana", Font.BOLD ,18));
JPanel pnTexto = new JPanel();
pnTexto.add(etTexto);
add(pnTexto, BorderLayout.SOUTH);
setBorder(
BorderFactory.createCompoundBorder(BorderFactory.createRaisedSoftBevelBorder(),
BorderFactory.createEmptyBorder(15, 15, 15, 15)));
}
}
}

A la clase PanelPrincipal le añado un método para poder recibir el ActionListener que le asignaremos al boton "Gestionar Usuarios".
Código: [Seleccionar]
public void setAccionGestionUsuario(ActionListener accion) {
btUsuarios.addActionListener(accion);
}

Más adelante habrá que añadir otros métodos similares para las acciones de los otros botones.
Otra opción sería declarar los botones de estos paneles como PUBLIC, así desde la clase principal podríamos asignarle directamente las acciones sin tener que recurrir a un método setter

Las acciones de todos estos botones conviene escribirlas en la clase principal, para estar dentro del "ámbito total" y tener acceso al cardLayout, a los objetos que gestionarán Usuarios y Eventos, etc..

De este modo, evitamos tener que estar pasando referencias a estos objetos a través de los constructores de los paneles.
La pega es que la clase principal tendrá un montón de línea de código, pero bueno, para algo es la principal  ;D

Esta clase principal queda modificada de la siguiente manera para añadir el nuevo panel y escribir las nuevas acciones para los botones que de momento funcionan.
Marco cambios en negrita, para que se vea la dinámica que hay que seguir para ir añadiendo paneles y dotar de acciones a los botones.

El zip de Google Drive también ha sido actualizado

Citar
public final class JavaTicket extends JFrame{
   
   //Partes del MODELO
   private GestorUsuarios gestorUsuarios;
   private Usuario usuarioLogueado;
   
   //Partes de la VISTA
   private DialogoLogin dialogoLogin;
   private PanelPrincipal pnPrincipal;
   private PanelUsuarios pnUsuarios;
   private CardLayout cardLayout;
   private JPanel panelActivo;
   
   public JavaTicket() {
      
      iniciarModelo();
      iniciarVista();
      
      add(panelActivo);
      
      setTitle("Java Ticket");
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      pack();
      setLocationRelativeTo(null);
      setVisible(true);
   }
   
   private void iniciarModelo() {
      gestorUsuarios = new GestorUsuarios();
      usuarioLogueado = null;
   }
   
   private void iniciarVista() {
      //composicion panel principal
      pnPrincipal = new PanelPrincipal();
      pnPrincipal.setAccionGestionUsuario(new AccionGestionarUsuarios());
      //Composicion panel usuarios
      pnUsuarios = new PanelUsuarios();
      pnUsuarios.setAccionVolver(new AccionVolver());

      cardLayout = new CardLayout();
      panelActivo = new JPanel();
      panelActivo.setLayout(cardLayout);
      panelActivo.add(pnPrincipal, "principal");
      panelActivo.add(pnUsuarios, "usuarios");
      dialogoLogin = new DialogoLogin(this, true, gestorUsuarios);
      dialogoLogin.setAccionEnviar(new AccionEnviarLogin());
      dialogoLogin.setVisible(true);
   }
   
   //Accion para boton del dialogo login
   private class AccionEnviarLogin implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         usuarioLogueado = dialogoLogin.getUsuarioLogin();
         
         if (usuarioLogueado != null) {
            pnPrincipal.setSaludo("Bienvenido " + usuarioLogueado.getNombre());
            String clase = usuarioLogueado.getClass().getName();
            switch(clase) {
            case "usuarios.Administrador":
               pnPrincipal.activarPanel(true);
               break;
            case "usuarios.DeContenidos":
               pnPrincipal.activarPanel(false);
               break;
            case "usuarios.Limitado":
               pnPrincipal.activarPanel(false);
               break;
            }
            
            dialogoLogin.setVisible(false);
         }
      }
   }
   
   //Acciones para los botones del menu principal
   private class AccionGestionarUsuarios implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         cardLayout.show(panelActivo, "usuarios");
         
      }
   }

   
   //Acciones para los botones del menu gestionar usuarios
   private class AccionVolver implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         cardLayout.show(panelActivo, "principal");
      }
   }


   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         @Override
         public void run() {
            new JavaTicket();   
         }
      });
   }

}

NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Demo8v

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 12
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #9 en: 17 de Febrero 2021, 16:17 »
 
En realidad no sabes cuanto me estas ayudando, tengo la suerte de que las peores cosas sucedan en el ultimo momento. El día de mañana intentare conseguir un poco mas de tiempo (tal vez uno o dos días mas para poder hacer algo) ya que a mi computadora se le dio el gusto de arrruinarse. En serio le agradezco por su ayuda señor Kabuto.

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 983
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #10 en: 18 de Febrero 2021, 02:39 »
Lamento lo de tu computador, aunque quizás te sirva para ganar tiempo.
Algo más he podido añadir, funcionalidad para crear nuevos usuarios.

Uso otro JDialog con los campos necesarios para los atributos.
Dos JTextField para los nombres, dos JPasswordField  para recoger la contraseña dos veces y hacer la típica comprobación de que coinciden, un JSpinner con la edad (he limitado la edad mínima a 18 años, porque sí, porque me ha dado la gana xD ) y un JComboBox para escoger entre los tres posibles tipos de usuarios existentes:



Como esta JDialog no tiene que interactuar con otros elementos de la interfaz, simplemente hacer su labor y cerrarse cuando haya terminado, en su constructor sí va a recibir una referencia al objeto GestorUsuarios para que trabaje de forma autónoma.
El ActionListener de su botón si está escrito en esta misma clase, porque como digo, solo necesita interactuar con el gestor de usuarios.
Como expliqué antes, si necesitarse interactuar con la interfaz principal y/o más elementos, entonces el ActionListener sí lo escribiríamos en la clase principal.

Código: [Seleccionar]
public class DialogoCrearUsuario extends JDialog{

private GestorUsuarios gestorUsuarios;
private Font fuentePlana = new Font("Verdana", Font.PLAIN, 20);
private Font fuenteNegrita = new Font("Verdana", Font.PLAIN, 20);
private JTextField campoNombre;
private JTextField campoUser;
private JPasswordField campoPassword1;
private JPasswordField campoPassword2;
private JSpinner campoEdad;
private JComboBox<String> campoTipoUsuario;
private JButton btCrear;

public DialogoCrearUsuario(Frame padre, boolean modal, GestorUsuarios gestor) {
super(padre, modal);
gestorUsuarios = gestor;
iniciarComponentes();
setLayout(new BorderLayout());
add(new PanelTitulo(), BorderLayout.NORTH);
add(new PanelDatos(), BorderLayout.CENTER);
add(new PanelBoton(), BorderLayout.SOUTH);

setTitle("Crear Usuario");
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
pack();
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
}

private void iniciarComponentes() {
campoNombre = new JTextField(10);
campoNombre.setFont(fuentePlana);
campoNombre.setForeground(Color.BLUE);
campoUser = new JTextField(10);
campoUser.setFont(fuentePlana);
campoUser.setForeground(Color.BLUE);
campoPassword1 = new JPasswordField(10);
campoPassword1.setFont(fuentePlana);
campoPassword1.setForeground(Color.BLUE);
campoPassword2 = new JPasswordField(10);
campoPassword2.setFont(fuentePlana);
campoPassword2.setForeground(Color.BLUE);
campoEdad = new JSpinner();
campoEdad.setFont(fuentePlana);
campoEdad.setForeground(Color.BLUE);
SpinnerNumberModel modeloSpinner = new SpinnerNumberModel();
modeloSpinner.setMinimum(18);
modeloSpinner.setValue(20);
campoEdad.setModel(modeloSpinner);
campoTipoUsuario = new JComboBox<String>(new String[] {"Administrador", "DeContenidos", "Limitado"});
campoTipoUsuario.setFont(fuentePlana);
campoTipoUsuario.setForeground(Color.BLUE);
campoTipoUsuario.setBackground(Color.WHITE);
btCrear = new JButton("Crear Usuario");
btCrear.setFont(fuenteNegrita);
btCrear.setForeground(Color.BLUE);
btCrear.addActionListener(new AccionCrear());
}

private class PanelTitulo extends JPanel {

public PanelTitulo() {
JLabel titulo = new JLabel("Crear Nuevo Usuario");
titulo.setFont(new Font("Verdana", Font.ITALIC, 32));
JPanel pnBienvenido = new JPanel();
pnBienvenido.add(titulo);
pnBienvenido.setBorder(BorderFactory.createLoweredSoftBevelBorder());
add(pnBienvenido);
}
}

private class PanelDatos extends JPanel {

public PanelDatos() {
setLayout(new GridLayout(3, 2, 4, 4));
add(new PanelConEtiqueta("Nombre Completo: ", campoNombre, FlowLayout.RIGHT));
add(new PanelConEtiqueta("Nombre Usuario: ", campoUser, FlowLayout.RIGHT));
add(new PanelConEtiqueta("Indique contraseña: ", campoPassword1, FlowLayout.RIGHT));
add(new PanelConEtiqueta("Repita contraseña: ", campoPassword2, FlowLayout.RIGHT));
add(new PanelConEtiqueta("Edad: ", campoEdad, FlowLayout.CENTER));
add(new PanelConEtiqueta("Tipo de Usuario: ", campoTipoUsuario, FlowLayout.CENTER));
setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
}
}

private class PanelBoton extends JPanel {

public PanelBoton() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(new JSeparator(SwingConstants.HORIZONTAL));
JPanel pnBoton = new JPanel();
pnBoton.add(btCrear);
pnBoton.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
add(pnBoton);
}
}

private class PanelConEtiqueta extends JPanel {

public PanelConEtiqueta(String textoEtiq, JComponent componente, int flotar) {
JLabel etiqueta = new JLabel(textoEtiq);
etiqueta.setFont(fuenteNegrita);
setLayout(new FlowLayout(flotar));
add(etiqueta);
add(componente);
}
}

private class AccionCrear implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
if (compruebaCampos()) {
String nombreComp = campoNombre.getText();
String nombreUser = campoUser.getText();
String password = String.valueOf(campoPassword1.getPassword());
String password2 = String.valueOf(campoPassword2.getPassword());
if (password.equals(password2)) {
int edad = (int) campoEdad.getValue();
String tipo = (String) campoTipoUsuario.getSelectedItem();
Usuario nuevo;
switch(tipo) {
case "Administrador":
nuevo = new Administrador(nombreComp, nombreUser, password, edad);
break;
case "DeContenidos":
nuevo = new DeContenidos(nombreComp, nombreUser, password, edad);
break;
default:
nuevo = new Limitado(nombreComp, nombreUser, password, edad);
}
if (gestorUsuarios.agregarUsuario(nuevo)) {
JOptionPane.showMessageDialog(null, "Nuevo Usuario creado",
"Crear Usuario", JOptionPane.INFORMATION_MESSAGE);
gestorUsuarios.guardarUsuarios();
cerrarDialogo(); //Cierra este JDialog
}
}
else
advertencia("Las contraseñas no coinciden");
}
}

}

private boolean compruebaCampos() {
if (campoNombre.getText().isEmpty() || campoNombre.getText().isBlank()) {
advertencia("El campo Nombre Completo no puede estar vacío");
return false;
}
if (campoUser.getText().isEmpty() || campoUser.getText().isBlank()) {
advertencia("El campo Nombre Usuario no puede estar vacío");
return false;
}
if (campoPassword1.getPassword().length == 0) {
advertencia("El campo Contraseña no puede estar vacío");
return false;
}
if (campoPassword2.getPassword().length == 0) {
advertencia("El campo Confirmar Contraseña no puede estar vacío");
return false;
}

return true; //Todo OK
}

private void advertencia(String texto) {
JOptionPane.showMessageDialog(this, texto, "Crear Usuario", JOptionPane.WARNING_MESSAGE);
}

private void cerrarDialogo() {
dispose();
}
}

Para que este JDialog aparezca al pulsar el botón de Nuevo Usuario en el panel de gestión de usuarios, si tenemos que escribir un ActionListener en la clase principal.

Código: [Seleccionar]
private class AccionNuevo implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
new DialogoCrearUsuario(null, true, gestorUsuarios);
}
}

Esta accion, se la hacemos llegar al botón correspondiente:

Citar
   private void iniciarVista() {
      //composicion panel principal
      pnPrincipal = new PanelPrincipal();
      pnPrincipal.setAccionGestionUsuario(new AccionGestionarUsuarios());
      //Composicion panel usuarios
      pnUsuarios = new PanelUsuarios();
      pnUsuarios.setAccionNuevo(new AccionNuevo());
      pnUsuarios.setAccionVolver(new AccionVolver());
      cardLayout = new CardLayout();
      panelActivo = new JPanel();
      panelActivo.setLayout(cardLayout);
      panelActivo.add(pnPrincipal, "principal");
      panelActivo.add(pnUsuarios, "usuarios");
      dialogoLogin = new DialogoLogin(this, true, gestorUsuarios);
      dialogoLogin.setAccionEnviar(new AccionEnviarLogin());
      dialogoLogin.setVisible(true);
   }

...usando un método que le hemos añadido a la clase PanelUsuarios:

Código: [Seleccionar]
public void setAccionNuevo(ActionListener accion) {
btNuevo.addActionListener(accion);
}


Y ahora podemos crear nuevos usuarios... pero claro, al cerrar programa se pierden. Así que conviene darles persistencia guardando en disco los datos de algún modo.
Lo más rápido, es "serializar" el ArrayList de Usuarios para guardarlo en disco.

Para lograr esto, lo primero es hacer que la clase Usuario implemente la interfaz Serializable

Citar
public abstract class Usuario implements Serializable{
   
   private String nombre;
   private String userName;
   private String password;
   private int edad;
   

Ahora, nos vamos a la clase GestionUsuarios y añadiremos código para que al iniciar el programa intente recuperar el fichero con los datos de usuario, si es que existe.
Primero añadimos un objeto File como atributo con la ruta que donde deseamos guardar el archivo con el ArrayList serializado.
Interesa que sea una ruta donde sepamos no habrá problema de permisos de escritura por parte del sistema operativo.
Citar
public class GestorUsuarios {

   private final File FICHERO_USERS = new File("C:/JavaTicket/usuarios.dat");
   private ArrayList<Usuario> usuarios;

Luego un método para intentar leer este fichero.
Tenemos que contemplar la posibilidad de que no exista, o que exista pero no hay permisos de acceso, o los datos se han corrompido, etc...
Si ocurre algo de estas posibilidades, lo notificamos con un mensaje y el ArrayList lo inicializamos nuevo, solo con el usuario Administrador que viene por defecto.

Si todo va bien, y el fichero existe y es accesible, lo recuperamos de disco y lo asignamos al atributo ArrayList. De este modo obtendremos los usuarios creados en sesiones anteriores.
Código: [Seleccionar]
private void cargarUsuarios() {
if (FICHERO_USERS.exists()) {
ObjectInputStream ois;
try {
ois = new ObjectInputStream(new FileInputStream(FICHERO_USERS));
Object aux = ois.readObject();
if (aux instanceof ArrayList) {
usuarios = (ArrayList<Usuario>) aux;
}
else {
JOptionPane.showMessageDialog(null, "No se reconocen los tipos de dato del fichero: "
+ FICHERO_USERS.getPath(), "Leer usuarios", JOptionPane.WARNING_MESSAGE);
usuarios = new ArrayList<Usuario>();
usuarios.add(new Administrador("Administrador", "admin", "admin", 20));
}
ois.close();
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(null, "No se encuentra fichero de Usuarios en ruta: "
+ FICHERO_USERS.getPath(), "Leer usuarios", JOptionPane.WARNING_MESSAGE);
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "No se puede acceder a fichero de Usuarios en ruta: "
+ FICHERO_USERS.getPath(), "Leer usuarios", JOptionPane.WARNING_MESSAGE);
} catch (ClassNotFoundException e) {
JOptionPane.showMessageDialog(null, "Objeto de clase desconocida en fichero: "
+ FICHERO_USERS.getPath(), "Leer usuarios", JOptionPane.WARNING_MESSAGE);
}
}
else {
usuarios = new ArrayList<Usuario>();
usuarios.add(new Administrador("Administrador", "admin", "admin", 20));
}
}

Este método lo llamaremos en el constructor de la clase, para que sea lo primero que haga.
Código: [Seleccionar]
public GestorUsuarios() {
cargarUsuarios();
}

Ahora nos falta un método para hacer lo opuesto, guardar el ArrayList en disco.
Este método será publico porque lo llamaremos desde otras clases. De hecho, en el código del JDialog para crear usuarios que he puesto al principio, ya invoco este método despues de que el gestor de usuarios me confirme que ha logrado registrar el nuevo usuario.

El método que guarda estos datos, también ha de contemplar la posibilidad de que no exista ese fichero, en cuyo caso, primero creará la carpeta que lo va a contener y luego creará el archivo.

Código: [Seleccionar]
public void guardarUsuarios() {

try {
if (!FICHERO_USERS.exists()) {
File carpeta = new File("C:/JavaTicket");
carpeta.mkdirs();

FICHERO_USERS.createNewFile();
}

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FICHERO_USERS));
oos.writeObject(usuarios); //Guardamos el ArrayList
oos.close();
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(null, "No se encuentra fichero de Usuarios en ruta: "
+ FICHERO_USERS.getPath(), "Guardar usuarios", JOptionPane.WARNING_MESSAGE);
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "No se puede acceder a fichero de Usuarios en ruta: "
+ FICHERO_USERS.getPath(), "Guardar usuarios", JOptionPane.WARNING_MESSAGE);
}
}

De este modo, ahora la próxima vez que iniciemos el programa, se conservarán los usuarios que hayamos creado y podremos hacer login con ellos.
Aquí por ejemplo hago login con un usuario de tipo "De Contenidos", el cuál no puede gestionar usuarios y por eso tiene el botón desactivado.




Y bueno, como puede verse, la dinámica vendrá a ser la misma. Para cada botón lanzar un JDialog (o si no paneles agregados en el CardLayout) con los elementos Swing necesarios para cumplir su función.
Escribir el listener correspondiente para su botón de acción y actualizar la clase principal para que incluya estos nuevos añadidos.

Enlace a Google Drive actualizado
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Demo8v

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 12
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #11 en: 19 de Febrero 2021, 04:20 »
Logré conseguir tiempo, me dieron hasta el domingo para poder presentarlo. Lo único que falta es que me arreglen mi computador pronto para finalizar el proyecto. Espero me puedas seguir ayudando  :'(  si puedes, claro.


Me he dado cuenta que implementaste un método de guardar los usuarios en un disco y eso es algo que aun no nos enseñan en clase, pero creo que puedo tomarme la libertad de ser autodidacta y estudiarlo por mi cuenta, tu descuida  y sigue con lo tuyo. Me alegra saber que me estas ayudando, aunque poco creo que se logre terminr antes del domingo y solo si es posible, me gustaria que aun asi me ayudes o me muestres como seria el programa completo. Yo creo que despues de todo tendre que retirar la clase ya que no lo he hecho muy bien ya que estoy a my poco de perderla y sin olvidar de que me quede sin computador. Aun asi intentare hacer lo posible para llegar a tal punto aunque la situacion no se  pinte bien.
Saludos
« Última modificación: 17 de Abril 2022, 18:50 por Alex Rodríguez »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 983
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #12 en: 20 de Febrero 2021, 00:58 »
Lo de guardar en disco, es porque para poder poner a prueba el programa, sería terrible que cada vez que iniciamos el programa, tuviéramos que registrar nuevos usuarios y registrar nuevos eventos, para comprobar si lo último que hemos añadido funciona bien o no.

Así que, o guardamos en disco los usuarios y eventos que iremos generando...
O bien, generamos por código una serie de usuarios y eventos.

En mi código ya has visto que si no hay datos guardados en disco, genero automáticamente un usuario Administrador.
Pues igual que genero uno, podemos generar mediante código 10, 20.. los que queramos.

Si crees que por añadir lo de guardar en disco te lo van a cuestionar por ser algo que aún no te han explicado, puedes optar por lo de generar usuarios mediante código.

Si mantienes lo de guardar en disco, asegúrate de que entiendes bien como funciona, por si te lo preguntan, pues que puedas explicarlo.

Tu pregunta por aquí cualquier cosa que no entiendas. Todo lo que voy añadiendo intento explicarlo paso a paso, pero puede que algo requiera explicaciones extra.

Dicho esto, he añadido nuevas funcionalidades.
Ya podemos modificar y borrar usuarios. Para ello usamos un nueva clase JDialog, la cuál para ahorrar tiempo y código, la he escrito de forma que nos va a servir para ambas funcionalidades.
En su constructor incluyo un boolean, y según su valor, el JDialog se construye con la funcionalidad de modificar o con la de borrar.

Para ambas cosas nos va a servir el mismo formulario.
El formulario consiste en un ComboBox para seleccionar un Usuario de los que hay registrados en el Gestor de Usuarios.
Debajo de este combobox tenemos los campos que muestran los atributos del usuario que hayamos seleccionado.
Y debajo un botón de acción

Si estamos en "modo modificar", los campos de texto son editables, excepto el selector de tipo de Usuario.
Para simplificarlo, no vamos a permitir cambiar la clase de un Usuario. Se podría hacer, pero implica eliminar el usuario anterior, crearlo de nuevo bajo la nueva clase seleccionada, transferirles los id's de eventos que tuviera asociados....
No vale la pena complicarse con esto.



Cuando pulsamos el botón en "modo modificar", se recuperan los valores de los campos de texto, se setean en el usuario seleccionado y se le pide al gestor que guarde los cambios en disco.


Cuando estamos en "modo borrar", que recuerdo vamos a usar un boolean para elegir un modo u otro, los campos no son editables. Se muestran los datos del usuario pero no se pueden cambiar.
El botón de acción lo que hará será pedir confirmación antes de borrar, y si se confirma, se elimina el usuario del combobox, luego se elimina del Gestor de Usuarios y se guarda en disco el cambio realizado.



Ambas funcionalidades, la conseguimos con una única clase, que se construirá de un modo u otro según el valor del boolean llamado "modoBorrar" que se recibe por el constructor.

Código: [Seleccionar]
public class DialogoModificarUsuario extends JDialog{

private boolean modoBorrar; //Indica si este dialogo ha de ser para borrar usuario, y no modificar
private GestorUsuarios gestorUsuarios;
private Font fuentePlana = new Font("Verdana", Font.PLAIN, 20);
private Font fuenteNegrita = new Font("Verdana", Font.PLAIN, 20);
private JTextField campoNombre;
private JTextField campoUser;
private JPasswordField campoPassword1;
private JPasswordField campoPassword2;
private JSpinner campoEdad;
private JComboBox<String> campoTipoUsuario;
private JButton btAccion; //Su accion será distinta según si el dialogo es para borrar o modificar

//Este ComboBox permitirá seleccionar usuarios registrados
private JComboBox<Usuario> comboUsuarios;

//Usuario actualmente seleccionado
private Usuario escogido;

public DialogoModificarUsuario(Frame padre, boolean modal, boolean modoBorrar, GestorUsuarios gestor) {
super(padre, modal);
this.modoBorrar = modoBorrar;
gestorUsuarios = gestor;
iniciarComponentes();
mostrarEscogido();

setLayout(new BorderLayout());

add(new PanelTitulo(), BorderLayout.NORTH);
JPanel pnCentro = new JPanel();
pnCentro.setLayout(new BoxLayout(pnCentro, BoxLayout.Y_AXIS));
pnCentro.add(new PanelSelectorUsuario());
pnCentro.add(new JSeparator(SwingConstants.HORIZONTAL));
pnCentro.add(new PanelDatos());
add(pnCentro, BorderLayout.CENTER);
add(new PanelBoton(), BorderLayout.SOUTH);

setTitle(modoBorrar?"Borrar Usuario":"Modificar Usuario");
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
pack();
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
}

private void iniciarComponentes() {
campoNombre = new JTextField(10);
campoNombre.setFont(fuentePlana);
campoNombre.setForeground(Color.BLUE);
campoNombre.setEditable(!modoBorrar); //En modo Borrar, no se pueden editar datos
campoUser = new JTextField(10);
campoUser.setFont(fuentePlana);
campoUser.setForeground(Color.BLUE);
campoUser.setEditable(!modoBorrar);
campoPassword1 = new JPasswordField(10);
campoPassword1.setFont(fuentePlana);
campoPassword1.setForeground(Color.BLUE);
campoPassword1.setEditable(!modoBorrar);
campoPassword2 = new JPasswordField(10);
campoPassword2.setFont(fuentePlana);
campoPassword2.setForeground(Color.BLUE);
campoPassword2.setEditable(!modoBorrar);
campoEdad = new JSpinner();
campoEdad.setFont(fuentePlana);
campoEdad.setForeground(Color.BLUE);
campoEdad.setEnabled(!modoBorrar);
SpinnerNumberModel modeloSpinner = new SpinnerNumberModel();
modeloSpinner.setMinimum(18);
modeloSpinner.setValue(20);
campoEdad.setModel(modeloSpinner);
campoTipoUsuario = new JComboBox<String>(new String[] {"Administrador", "DeContenidos", "Limitado"});
campoTipoUsuario.setFont(fuentePlana);
campoTipoUsuario.setForeground(Color.BLUE);
campoTipoUsuario.setBackground(Color.WHITE);
campoTipoUsuario.setEnabled(false); //Siempre desactivado, no se puede modificar el tipo usuario
btAccion = new JButton(modoBorrar?"Borrar Usuario":"Modificar Usuario");
btAccion.setFont(fuenteNegrita);
btAccion.setForeground(Color.BLUE);
if (modoBorrar)
btAccion.addActionListener(new AccionBorrar());
else
btAccion.addActionListener(new AccionModificar());
comboUsuarios = new JComboBox<Usuario>(gestorUsuarios.getArrayUsuarios());
comboUsuarios.setFont(fuenteNegrita);
comboUsuarios.addActionListener(new AccionEscoger());
}

private void mostrarEscogido() {
escogido = (Usuario) comboUsuarios.getSelectedItem();

campoNombre.setText(escogido.getNombre());
campoUser.setText(escogido.getUserName());
campoPassword1.setText(escogido.getPassword());
campoPassword2.setText(escogido.getPassword());
campoEdad.setValue(escogido.getEdad());
if (escogido instanceof Administrador)
campoTipoUsuario.setSelectedIndex(0);
else if (escogido instanceof DeContenidos)
campoTipoUsuario.setSelectedIndex(1);
else
campoTipoUsuario.setSelectedIndex(2);
}

private boolean compruebaCampos() {
if (campoNombre.getText().isEmpty() || campoNombre.getText().isBlank()) {
advertencia("El campo Nombre Completo no puede estar vacío");
return false;
}
if (campoUser.getText().isEmpty() || campoUser.getText().isBlank()) {
advertencia("El campo Nombre Usuario no puede estar vacío");
return false;
}
if (campoPassword1.getPassword().length == 0) {
advertencia("El campo Contraseña no puede estar vacío");
return false;
}
if (campoPassword2.getPassword().length == 0) {
advertencia("El campo Confirmar Contraseña no puede estar vacío");
return false;
}

return true; //Todo OK
}

private void advertencia(String texto) {
JOptionPane.showMessageDialog(this, texto, "Crear Usuario", JOptionPane.WARNING_MESSAGE);
}

private class PanelTitulo extends JPanel {

public PanelTitulo() {
JLabel titulo = new JLabel(modoBorrar?"Eliminar Usuario":"Modificar Usuario");
titulo.setFont(new Font("Verdana", Font.ITALIC, 32));
JPanel pnBienvenido = new JPanel();
pnBienvenido.add(titulo);
pnBienvenido.setBorder(BorderFactory.createLoweredSoftBevelBorder());
add(pnBienvenido);
}
}

private class PanelSelectorUsuario extends JPanel {

public PanelSelectorUsuario() {
add(comboUsuarios);
TitledBorder bordeTitulo = new TitledBorder("Escoja Usuario");
bordeTitulo.setTitleFont(fuentePlana);
setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20),
bordeTitulo));
}

}

private class PanelDatos extends JPanel {

public PanelDatos() {
setLayout(new GridLayout(3, 2, 4, 4));
add(new PanelConEtiqueta("Nombre Completo: ", campoNombre, FlowLayout.RIGHT));
add(new PanelConEtiqueta("Nombre Usuario: ", campoUser, FlowLayout.RIGHT));
add(new PanelConEtiqueta("Indique contraseña: ", campoPassword1, FlowLayout.RIGHT));
add(new PanelConEtiqueta("Repita contraseña: ", campoPassword2, FlowLayout.RIGHT));
add(new PanelConEtiqueta("Edad: ", campoEdad, FlowLayout.CENTER));
add(new PanelConEtiqueta("Tipo de Usuario: ", campoTipoUsuario, FlowLayout.CENTER));
setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
}
}

private class PanelBoton extends JPanel {

public PanelBoton() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(new JSeparator(SwingConstants.HORIZONTAL));
JPanel pnBoton = new JPanel();
pnBoton.add(btAccion);
pnBoton.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
add(pnBoton);
}
}

private class PanelConEtiqueta extends JPanel {

public PanelConEtiqueta(String textoEtiq, JComponent componente, int flotar) {
JLabel etiqueta = new JLabel(textoEtiq);
etiqueta.setFont(fuenteNegrita);
setLayout(new FlowLayout(flotar));
add(etiqueta);
add(componente);
}
}

private class AccionEscoger implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
mostrarEscogido();
}
}

private class AccionModificar implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (compruebaCampos()) {
String nombreComp = campoNombre.getText();
String nombreUser = campoUser.getText();
String password = String.valueOf(campoPassword1.getPassword());
String password2 = String.valueOf(campoPassword2.getPassword());
int edad = (int) campoEdad.getValue();
if (password.equals(password2)) {
escogido.setNombre(nombreComp);
escogido.setUserName(nombreUser);
escogido.setEdad(edad);
escogido.setPassword(password);
gestorUsuarios.guardarUsuarios();
JOptionPane.showMessageDialog(null, "Usuario modificado",
"Modificar Usuario", JOptionPane.INFORMATION_MESSAGE);
}
else
advertencia("Las contraseñas no coinciden");
}
}
}

private class AccionBorrar implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
int respuesta = JOptionPane.showConfirmDialog(null,
"¿Seguro que quiere borrar este Usuario",
"Borrar Usuarios", JOptionPane.YES_NO_OPTION);
if (respuesta == JOptionPane.YES_OPTION) {
//Eliminamos del Gestor de usuarios
gestorUsuarios.borrarUsuario(escogido);
gestorUsuarios.guardarUsuarios();
//Eliminamos del combobox
comboUsuarios.removeItem(escogido);
}
}
}

}

Fijémonos en el JComboBox de Usuarios. Este combo no va a ser de tipo <String>, es decir, no es que simplemente muestre los nombres.
Es de tipo <Usuario>, es decir, contiene en su interior los objetos Usuario que recibe del Gestor de Usuarios.
Para poder recibirlos de forma fácil, lo que vamos a hacer es añadir un método a la clase GestorUsuarios que nos construya un array simple con todos los usuarios que hay registrados.
Código: [Seleccionar]
public Usuario[] getArrayUsuarios() {
Usuario[] arrayUsers = new Usuario[usuarios.size()];
for (int i = 0; i < usuarios.size(); i++)
arrayUsers[i] = usuarios.get(i);

return arrayUsers;

}

Gracias a este método, luego podemos construir rápidamente el combobox con esta línea:
Código: [Seleccionar]
comboUsuarios = new JComboBox<Usuario>(gestorUsuarios.getArrayUsuarios());
Sin embargo, esto no es suficiente. El combobox ahora contiene objetos de tipo Usuarios, bien, pero para mostrar en pantalla necesita mostrar un String que represente a cada uno de estos objetos.
Para hacer esto, el combobox va a mostrar lo que le devuelva el método toString() de cada uno de estos objetos. Este método lo heredan TODAS las clases de Java, pero para que funcione bien y lo haga según nuestras necesidades, tenemos que sobreescribirlo.

Así que nos vamos a ir a la clase padre Usuario y vamos a sobreescribir este método.
Yo he optado por hacer que muestre el nombre completo de la persona y a continuación el nombre de usuario con el que ha elegido registrarse.
Código: [Seleccionar]
@Override
public String toString() {
return nombre + " -- " + userName;
}

¡¡ATENCIÓN!!
Al modificar esta clase, por desgracia, los datos que tuviéramos guardados en disco ya no nos van a servir.
Este es uno de los inconvenientes de guardar datos de forma "serializada". Si alteramos el código de la clase de los objetos que estamos guardando, luego al intentar recuperarlos no sirven porque están creados con el código de clase anterior y se produce una excepción.

Así que tras hacer este cambio en la clase Usuario, lo mejor es borrar el archivo donde estemos guardando los usuarios (yo lo guardo en C:\JavaTicket\usuarios.dat) y que se genere uno nuevo.

(Continúa en el siguiente post)
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 983
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #13 en: 20 de Febrero 2021, 00:58 »
Volviendo a la clase DialogoModificarUsuario
En su constructor vemos que gracias al boolean modoBorrar:
Citar
public DialogoModificarUsuario(Frame padre, boolean modal, boolean modoBorrar, GestorUsuarios gestor)

Cambia la construcción del dialogo para adaptarse a una funcionalidad o a otra.
Si el valor de ese boolean es TRUE, entonces estamos en modo borrar, y por ejemplo los campos con los datos queremos que NO se puedan editar.
Así que a sus métodos setEditable() les decimos FALSE. O sea, lo contrario de este boolean. Por lo tanto, nos basta con "negar" este boolean y pasárselo como argumento.
Citar
campoNombre.setEditable(!modoBorrar); //En modo Borrar, no se pueden editar datos
      campoUser = new JTextField(10);
      campoUser.setFont(fuentePlana);
      campoUser.setForeground(Color.BLUE);
      campoUser.setEditable(!modoBorrar);

Así, cuando modoBorrar sea TRUE, poder editar campos será FALSE. Y cuando modoBorrar sea FALSE, poder editar campos será TRUE.

El botón de acción también cambia de nombre, y de acción, según el valor de este boolean

Citar
btAccion = new JButton(modoBorrar?"Borrar Usuario":"Modificar Usuario");
      btAccion.setFont(fuenteNegrita);
      btAccion.setForeground(Color.BLUE);
      if (modoBorrar)
         btAccion.addActionListener(new AccionBorrar());
      else
         btAccion.addActionListener(new AccionModificar());


Sobre las acciones de esta clase.
Tenemos tres acciones, una es para el combobox de Usuarios. Las otras dos son para el botón de acción, pero escogerá una u otra según si estamos en modo borrar o no.

La acción del combobox se ejecuta cada vez que elegimos uno de los items que contiene. Lo que hace es coger el usuario seleccionado y pasar una referencia a un atributo llamado "escogido"

Citar
   //Usuario actualmente seleccionado
   private Usuario escogido;
Este atributo apunta al Usuario seleccionado en el combobox, para saber que usuario ha de mostrar sus atributos en pantalla, o ha de ser modificado, o ha de ser borrado.

Así, esta acción del combobox.
Código: [Seleccionar]
private class AccionEscoger implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
mostrarEscogido();
}
}

Invoca este método para seleccionar al "escogido" y mostrar sus datos.

Código: [Seleccionar]
private void mostrarEscogido() {
escogido = (Usuario) comboUsuarios.getSelectedItem();

campoNombre.setText(escogido.getNombre());
campoUser.setText(escogido.getUserName());
campoPassword1.setText(escogido.getPassword());
campoPassword2.setText(escogido.getPassword());
campoEdad.setValue(escogido.getEdad());
if (escogido instanceof Administrador)
campoTipoUsuario.setSelectedIndex(0);
else if (escogido instanceof DeContenidos)
campoTipoUsuario.setSelectedIndex(1);
else
campoTipoUsuario.setSelectedIndex(2);
}

Luego, el botón de acción.
Para modificar se ejecuta este código, que comprueba que los campos tengan datos, que las contraseñas coincidan y si todo está bien, se modifican los atributos del usuario escogido.

Código: [Seleccionar]
private class AccionModificar implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (compruebaCampos()) {
String nombreComp = campoNombre.getText();
String nombreUser = campoUser.getText();
String password = String.valueOf(campoPassword1.getPassword());
String password2 = String.valueOf(campoPassword2.getPassword());
int edad = (int) campoEdad.getValue();
if (password.equals(password2)) {
escogido.setNombre(nombreComp);
escogido.setUserName(nombreUser);
escogido.setEdad(edad);
escogido.setPassword(password);
gestorUsuarios.guardarUsuarios();
JOptionPane.showMessageDialog(null, "Usuario modificado",
"Modificar Usuario", JOptionPane.INFORMATION_MESSAGE);
}
else
advertencia("Las contraseñas no coinciden");
}
}
}

Y luego, esta acción, para cuando estamos en "modo Borrar"
Código: [Seleccionar]
private class AccionBorrar implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
int respuesta = JOptionPane.showConfirmDialog(null,
"¿Seguro que quiere borrar este Usuario",
"Borrar Usuarios", JOptionPane.YES_NO_OPTION);
if (respuesta == JOptionPane.YES_OPTION) {
//Eliminamos del Gestor de usuarios
gestorUsuarios.borrarUsuario(escogido);
gestorUsuarios.guardarUsuarios();
//Eliminamos del combobox
comboUsuarios.removeItem(escogido);
}
}
}

Por último, para que poder usar este JDialog.
En la clase principal escribimos estas dos acciones, donde ambas llaman a este JDialog pero con un valor distinto para el boolean "modoBorrar"

Código: [Seleccionar]
private class AccionModificar implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
new DialogoModificarUsuario(null, true, false, gestorUsuarios);
}
}

private class AccionBorrar implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
new DialogoModificarUsuario(null, true, true, gestorUsuarios);
}
}
Estas acciones, las agregamos al panel de usuarios:
Código: [Seleccionar]
private void iniciarVista() {
//composicion panel principal
pnPrincipal = new PanelPrincipal();
pnPrincipal.setAccionGestionUsuario(new AccionGestionarUsuarios());
//Composicion panel usuarios
pnUsuarios = new PanelUsuarios();
pnUsuarios.setAccionNuevo(new AccionNuevo());
[b]pnUsuarios.setAccionModificar(new AccionModificar());
pnUsuarios.setAccionEliminar(new AccionBorrar());[/b]
pnUsuarios.setAccionVolver(new AccionVolver());
cardLayout = new CardLayout();
panelActivo = new JPanel();
panelActivo.setLayout(cardLayout);
panelActivo.add(pnPrincipal, "principal");
panelActivo.add(pnUsuarios, "usuarios");
dialogoLogin = new DialogoLogin(this, true, gestorUsuarios);
dialogoLogin.setAccionEnviar(new AccionEnviarLogin());
dialogoLogin.setVisible(true);
}

Para poder hacer esta agregación, a la clase PanelUsuarios hay que escribirle estos dos métodos:
Código: [Seleccionar]
public void setAccionModificar(ActionListener accion) {
btModificar.addActionListener(accion);
}

public void setAccionEliminar(ActionListener accion) {
btEliminar.addActionListener(accion);
}

Y con esto, la parte de la gestión de Usuarios creo que quedaría completa.

Enlace a Google Drive
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 983
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #14 en: 20 de Febrero 2021, 01:39 »
OK.
Me estoy mirando la parte de gestionar eventos y me he dado cuenta de que el enunciado incorpora unos atributos extra para las clases de eventos que no había visto antes.
Atributos que sus valores serían establecidos desde el apartado "modificar evento".

Lo eventos Religiosos pueden anotarse cuántos convertidos han conseguido tras dicho evento.
Lo lógico sería pues que solo una vez el evento haya tenido lugar, según su fecha, se permitiera apuntar estos convertidos.
Pero no se especifica nada sobre esto, así que no nos vamos a complicar con eso.
De momento, a su clase le añado este atributo y sus getter/setter

Citar
public final class Religioso extends Evento{

   //Constante que establece el limite de personas que pueden asistir a este evento
   private final int AFORO_MAXIMO = 30000;
   //Constante que establece el importe fijado como seguro por desgaste de la grama
   public final int CUOTA_SEGURO = 2000; //Public, no será necesario usar getter para acceder a este valor
   //Atributos
   private int aforo;
   //Atributo extra
   private int convertidos;

   public Religioso(String codigo, String titulo, String descripcion, String fecha, double renta,
         int aforo) {
      super(codigo, titulo, descripcion, fecha, renta);
      setAforo(aforo);
   }
   
   public int getAforo() {
      return aforo;
   }

   /**
    * Establece la cantidad de gente que asistirá al evento.<br>
    * Esta cantidad está limitada por la constante <i>AFORO_MAXIMO.</i>
    * @param aforo Cantidad de gente que asistirá al evento.
    */
   public void setAforo(int aforo) {
      if (aforo > AFORO_MAXIMO) {
         JOptionPane.showMessageDialog(null, "El aforo indicado supera el límite establecido."
               + "El aforo será establecido a " + AFORO_MAXIMO, "Crear Evento Derportivo",
               JOptionPane.WARNING_MESSAGE);
         this.aforo = AFORO_MAXIMO;
      }
      else
         this.aforo = aforo;
   }
   
   public void setConvertidos(int cantidad) {
      convertidos = cantidad;
   }
   
   public int getConvertidos() {
      return convertidos;
   }


}

Los Musicales se puede añadir los nombres del equipo de montaje a una lista.
Aún no he decidido como introducirá el usuario estos nombres. Quizás en un area de texto, con los nombres separados por ;  o algo así.
Luego podemos coger ese texto, hacer divisiones donde haya un ; para separar los nombres, componer un array con ellos y hacérselo llegar al ArrayList.
Ya veremos, de momento para su setter, cuento con hacerle llegar un array de nombres.
Para su getter, en cambio, construiríamos un String con los nombres separado por ; , similar a lo que el usuario hubiera escrito para introducirlos.

Citar
public final class Musical extends Evento{

   //Constante que establece el limite de personas que pueden asistir a este evento
   private final int AFORO_MAXIMO = 25000;
   //Constante que establece el % de cuota de seguro que se cobra sobre la renta acordada
   private final double CUOTA_SEGURO = 30d; //30%
   //Atributos
   private int aforo;
   private TipoMusica tipoMusica;
   //Atributo extra
   private ArrayList<String> staff; //Nombres de los miembros del equipo de montaje

   public Musical(String codigo, String titulo, String descripcion, String fecha, double renta,
         int aforo, TipoMusica tipoMusica) {
      super(codigo, titulo, descripcion, fecha, renta);
      setAforo(aforo);
      this.tipoMusica = tipoMusica;
      staff = new ArrayList<String>();
   }
   
   public int getAforo() {
      return aforo;
   }

   /**
    * Establece la cantidad de gente que asistirá al evento.<br>
    * Esta cantidad está limitada por la constante <i>AFORO_MAXIMO.</i>
    * @param aforo Cantidad de gente que asistirá al evento.
    */
   public void setAforo(int aforo) {
      if (aforo > AFORO_MAXIMO) {
         JOptionPane.showMessageDialog(null, "El aforo indicado supera el límite establecido."
               + "El aforo será establecido a " + AFORO_MAXIMO, "Crear Evento Derportivo",
               JOptionPane.WARNING_MESSAGE);
         this.aforo = AFORO_MAXIMO;
      }
      else
         this.aforo = aforo;
   }

   public TipoMusica getTipoMusica() {
      return tipoMusica;
   }

   public void setTipoMusica(TipoMusica tipoMusica) {
      this.tipoMusica = tipoMusica;
   }

   /**
    * Establece el importe del seguro que se cobra
    * por el uso de la grama.<br>Este importe es el
    * 30% del valor de la renta acordada.
    * @return Importe del seguro.
    */
   public double getImporteSeguro() {
      return  renta * CUOTA_SEGURO / 100;
   }
   
   public void setStaff(String[] lista) {
      for (String nombre: lista)
         staff.add(nombre);
   }

   
   public String getStaff() {
      StringBuilder lista = new StringBuilder();
      for (String nombre: staff)
         lista.append(nombre + ";\n");
      
      return lista.toString();
   }

   
}


En los Deportivos tenemos algo similar, listas de nombres con los jugadores de los equipos.
Citar
public final class Deportivo extends Evento{

   //Constante que establece el limite de personas que pueden asistir a este evento
   private final int AFORO_MAXIMO = 20000;
   //Atributos
   private int aforo;
   private String equipo1;
   private String equipo2;
   private TipoDeporte tipoDeporte;
   //Atributos extra
   private ArrayList<String> jugadores1;
   private ArrayList<String> jugadores2;


   public Deportivo(String codigo, String titulo, String descripcion, String fecha, double renta,
         int aforo, String equipo1, String equipo2, TipoDeporte tipoDeporte) {
      super(codigo, titulo, descripcion, fecha, renta);

      setAforo(aforo);
      this.equipo1 = equipo1;
      this.equipo2 = equipo2;
      this.tipoDeporte = tipoDeporte;
      jugadores1 = new ArrayList<String>();
      jugadores2 = new ArrayList<String>();

   }

   public int getAforo() {
      return aforo;
   }

   /**
    * Establece la cantidad de gente que asistirá al evento.<br>
    * Esta cantidad está limitada por la constante <i>AFORO_MAXIMO.</i>
    * @param aforo Cantidad de gente que asistirá al evento.
    */
   public void setAforo(int aforo) {
      if (aforo > AFORO_MAXIMO) {
         JOptionPane.showMessageDialog(null, "El aforo indicado supera el límite establecido."
               + "El aforo será establecido a " + AFORO_MAXIMO, "Crear Evento Derportivo",
               JOptionPane.WARNING_MESSAGE);
         this.aforo = AFORO_MAXIMO;
      }
      else
         this.aforo = aforo;
   }

   public String getEquipo1() {
      return equipo1;
   }

   public void setEquipo1(String equipo1) {
      this.equipo1 = equipo1;
   }

   public String getEquipo2() {
      return equipo2;
   }

   public void setEquipo2(String equipo2) {
      this.equipo2 = equipo2;
   }

   public TipoDeporte getTipoDeporte() {
      return tipoDeporte;
   }

   public void setTipoDeporte(TipoDeporte tipoDeporte) {
      this.tipoDeporte = tipoDeporte;
   }
   
   public void setJugadores1(String[] lista) {
      for (String nombre: lista)
         jugadores1.add(nombre);
   }
   
   public void setJugadores2(String[] lista) {
      for (String nombre: lista)
         jugadores2.add(nombre);
   }

   
   public String getJugadores1() {
      StringBuilder lista = new StringBuilder();
      for (String nombre: jugadores1)
         lista.append(nombre);
      
      return lista.toString();
   }

   
   public String getJugadores2() {
      StringBuilder lista = new StringBuilder();
      for (String nombre: jugadores2)
         lista.append(nombre);
      
      return lista.toString();
   }


}


También he visto que habrá que operar con las fechas de los eventos.
Este atributo, que está en la clase padre, lo puse como String por sencillez.
Pero no sabía que se iba a tener que operar con ellas, así pues, puede que nos convenga más usar la clase LocalDate.
Puede que luego vuelva a cambiar de opinión, pero seguramente cuando haya que escribir código para comparar fechas, será mejor contar con la clase LocalDate

Código: [Seleccionar]
public abstract class Evento {

private String codigo;
private String titulo;
private String descripcion;
private [b]LocalDate[/b] fecha;
protected double renta; //Protected porque algunas clases hijas necesitan verla para calcular seguro

public Evento(String codigo, String titulo, String descripcion, [b]LocalDate[/b] fecha, double renta) {
this.codigo = codigo;
this.titulo = titulo;
this.descripcion = descripcion;
this.fecha = fecha;
this.renta = renta;
}

public String getCodigo() {
return codigo;
}

public void setCodigo(String codigo) {
this.codigo = codigo;
}

public String getTitulo() {
return titulo;
}

public void setTitulo(String titulo) {
this.titulo = titulo;
}

public String getDescripcion() {
return descripcion;
}

public void setDescripcion(String descripcion) {
this.descripcion = descripcion;
}

public [b]LocalDate[/b] getFecha() {
return fecha;
}

public void setFecha([b]LocalDate[/b] fecha) {
this.fecha = fecha;
}

public double getRenta() {
return renta;
}

public void setRenta(double renta) {
this.renta = renta;
}

@Override
public boolean equals(Object obj) {

if (obj instanceof Evento) {
Evento otroEvento = (Evento)obj;
return otroEvento.codigo.equals(codigo);
}
else
return false;
}

}

Y se me acaba el tiempo... a ver si mañana podemos avanzar más.
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 983
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #15 en: 21 de Febrero 2021, 01:04 »
El siguiente paso sería crea el PanelEventos, con los botones para crear evento, cancelar, modificar, visualizar y volver al menú principal.
Será prácticamente igual que PanelUsuarios, pero con 5 botones en lugar de 4.



De momento, solo funcionará el botón para regresar al menú principal:

Código: [Seleccionar]
public final class PanelEventos extends JPanel{

private JButton btNuevo;
private JButton btCancelar;
private JButton btEditar;
private JButton btVisualizar;
private JButton btVolver;

public PanelEventos() {
iniciarBotones();

setLayout(new BorderLayout());
add(new PanelTitulo(), BorderLayout.NORTH);

JPanel pnCentro = new JPanel();
pnCentro.setLayout(new BoxLayout(pnCentro, BoxLayout.Y_AXIS));
//Tres botones en la fila superior
JPanel filaSup = new JPanel();
filaSup.setLayout(new GridLayout(1, 3, 10, 10));
filaSup.add(new PanelBoton(btNuevo, "Crear Evento"));
filaSup.add(new PanelBoton(btCancelar, "Cancelar Evento"));
filaSup.add(new PanelBoton(btEditar, "Editar EVento"));
//Dos botones en la fila inferior
JPanel filaInf = new JPanel();
filaInf.setLayout(new GridLayout(1, 2, 10, 10));
filaInf.add(new PanelBoton(btVisualizar, "Visualizar Evento"));
filaInf.add(new PanelBoton(btVolver, "Volver a menú principal"));
pnCentro.add(filaSup);
pnCentro.add(filaInf);
pnCentro.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
add(pnCentro, BorderLayout.CENTER);

}


private void iniciarBotones() {
btNuevo = new JButton();
btNuevo.setIcon(
new ImageIcon(PanelPrincipal.class.getClassLoader().getResource("img/crearTicket.png")));
btNuevo.setFocusPainted(false);

btCancelar = new JButton();
btCancelar.setIcon(
new ImageIcon(PanelPrincipal.class.getClassLoader().getResource("img/cancelarTicket.png")));
btCancelar.setFocusPainted(false);

btEditar = new JButton();
btEditar.setIcon(
new ImageIcon(PanelPrincipal.class.getClassLoader().getResource("img/modificarTicket.png")));
btEditar.setFocusPainted(false);

btVisualizar = new JButton();
btVisualizar.setIcon(
new ImageIcon(PanelPrincipal.class.getClassLoader().getResource("img/visualizarTicket.png")));
btVisualizar.setFocusPainted(false);

btVolver = new JButton();
btVolver.setIcon(
new ImageIcon(PanelPrincipal.class.getClassLoader().getResource("img/volver.png")));
}

public void setAccionVolver(ActionListener accion) {
btVolver.addActionListener(accion);
}

private class PanelTitulo extends JPanel {

public PanelTitulo() {
JLabel titulo = new JLabel("Administrar Eventos");
titulo.setFont(new Font("Verdana", Font.ITALIC, 32));
JPanel pnBienvenido = new JPanel();
pnBienvenido.add(titulo);
pnBienvenido.setBorder(BorderFactory.createLoweredSoftBevelBorder());
add(pnBienvenido);
}
}


private class PanelBoton extends JPanel {

public PanelBoton(JButton boton, String texto) {
setLayout(new BorderLayout());
add(boton, BorderLayout.CENTER);
JLabel etTexto = new JLabel(texto);
etTexto.setFont(new Font("Verdana", Font.BOLD ,18));
JPanel pnTexto = new JPanel();
pnTexto.add(etTexto);
add(pnTexto, BorderLayout.SOUTH);
setBorder(
BorderFactory.createCompoundBorder(BorderFactory.createRaisedSoftBevelBorder(),
BorderFactory.createEmptyBorder(15, 15, 15, 15)));
}
}
}

Para poder visualizar este nuevo panel en la interfaz, primero nos vamos a la clase PanelPrincipal y le añadimos un método para poder dotar de un ActionListener al botón "Gestionar Eventos"
Código: [Seleccionar]
public void setAccionGestionEventos(ActionListener accion) {
btEventos.addActionListener(accion);
}

Esta acción que recibirá, ha de ser escrita en la clase principal JavaTicket

Código: [Seleccionar]
private class AccionGestionarEventos implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
cardLayout.show(panelActivo, "evento");
}
}
Esta acción consiste en pedir al cardLayout, que en el "panel activo" muestre el panel de eventos, que está etiquetado como "evento".
Pero claro, para que esto funcione, primero hay que declarar este panel en la zona de atributos de esta clase:
Citar
public final class JavaTicket extends JFrame{
   
   //Partes del MODELO
   private GestorUsuarios gestorUsuarios;
   private Usuario usuarioLogueado;
   
   //Partes de la VISTA
   private DialogoLogin dialogoLogin;
   private PanelPrincipal pnPrincipal;
   private PanelEventos pnEventos;
   private PanelUsuarios pnUsuarios;
   private CardLayout cardLayout;
   private JPanel panelActivo;

Inicializar este panel, en el método iniciarVista() y de paso hacerle llegar el único ActionListener del que disponemos para él, el de volver al menú principal.
Que ya lo tenemos escrito porque es el mismo que el del botón "volver" del panel de gestión de usuarios.

Además lo agregamos al cardLayout del "panelActivo", etiquetándolo como "evento" para identificarlo

Citar
   private void iniciarVista() {
      //composicion panel principal
      pnPrincipal = new PanelPrincipal();
      pnPrincipal.setAccionGestionEventos(new AccionGestionarEventos());
      pnPrincipal.setAccionGestionUsuario(new AccionGestionarUsuarios());
      //Composicion panel eventos
      pnEventos = new PanelEventos();
      pnEventos.setAccionVolver(new AccionVolver());

      //Composicion panel usuarios
      pnUsuarios = new PanelUsuarios();
      pnUsuarios.setAccionNuevo(new AccionNuevo());
      pnUsuarios.setAccionModificar(new AccionModificar());
      pnUsuarios.setAccionEliminar(new AccionBorrar());
      pnUsuarios.setAccionVolver(new AccionVolver());
      cardLayout = new CardLayout();
      panelActivo = new JPanel();
      panelActivo.setLayout(cardLayout);
      panelActivo.add(pnPrincipal, "principal");
      panelActivo.add(pnEventos, "evento");
      panelActivo.add(pnUsuarios, "usuarios");
      dialogoLogin = new DialogoLogin(this, true, gestorUsuarios);
      dialogoLogin.setAccionEnviar(new AccionEnviarLogin());
      dialogoLogin.setVisible(true);
   }


Bien, ya tenemos panel para gestionar eventos. Ahora necesitamos un Gestor de Eventos, una clase que será casi idéntica a la clase GestionUsuarios.
Un ArrayList para añadir Eventos y poder guardarlos en disco para luego recuperarlos.
Código: [Seleccionar]
public final class GestorEventos {

private final File FICHERO_EVENTOS = new File("C:/JavaTicket/eventos.dat");
private ArrayList<Evento> eventos;

public GestorEventos() {
cargarEventos();
}

@SuppressWarnings("unchecked")
private void cargarEventos() {
if (FICHERO_EVENTOS.exists()) {
ObjectInputStream ois;
try {
ois = new ObjectInputStream(new FileInputStream(FICHERO_EVENTOS));
Object aux = ois.readObject();
if (aux instanceof ArrayList) {
eventos = (ArrayList<Evento>) aux;
}
else {
JOptionPane.showMessageDialog(null, "No se reconocen los tipos de dato del fichero: "
+ FICHERO_EVENTOS.getPath(), "Leer eventos", JOptionPane.WARNING_MESSAGE);
eventos = new ArrayList<Evento>();
}
ois.close();
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(null, "No se encuentra fichero de Eventos en ruta: "
+ FICHERO_EVENTOS.getPath(), "Leer eventos", JOptionPane.WARNING_MESSAGE);
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "No se puede acceder a fichero de Eventos en ruta: "
+ FICHERO_EVENTOS.getPath(), "Leer eventos", JOptionPane.WARNING_MESSAGE);
} catch (ClassNotFoundException e) {
JOptionPane.showMessageDialog(null, "Objeto de clase desconocida en fichero: "
+ FICHERO_EVENTOS.getPath(), "Leer eventos", JOptionPane.WARNING_MESSAGE);
}
}
else
eventos = new ArrayList<Evento>();
}

public void guardarUsuarios() {

try {
if (!FICHERO_EVENTOS.exists()) {
File carpeta = new File("C:/JavaTicket");
carpeta.mkdirs();

FICHERO_EVENTOS.createNewFile();
}

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FICHERO_EVENTOS));
oos.writeObject(eventos); //Guardamos el ArrayList
oos.close();
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(null, "No se encuentra fichero de Eventos en ruta: "
+ FICHERO_EVENTOS.getPath(), "Guardar Eventos", JOptionPane.WARNING_MESSAGE);
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "No se puede acceder a fichero de Eventos en ruta: "
+ FICHERO_EVENTOS.getPath(), "Guardar Eventos", JOptionPane.WARNING_MESSAGE);
}
}

public boolean agregarEvento(Evento evento) {
if (eventos.contains(evento)) {
JOptionPane.showMessageDialog(null, "Este Evento ya está registrado",
"Registrar nuevo Evento", JOptionPane.WARNING_MESSAGE);
return false;
}
else
return eventos.add(evento);
}

}

No le he añadido un método para eliminar eventos, porque leyendo el enunciado (cada vez que lo leo descubro algo nuevo) resulta que los eventos no se borran, SE CANCELAN.
Es decir, un evento que no se va a producir, se marca como cancelado, pero ha de seguir existiendo en el ArrayList.

Esto me ha hecho cambiar, otra vez más, la clase Evento a quién le he añadido un boolean para poder marcar como cancelado un evento.
Además del atributo, dos métodos para interactuar con él.

Y no solo eso, puesto que vamos a guardarlos en disco, ha de implementarse la interfaz Serializable

Citar
public abstract class Evento implements Serializable{

   private String codigo;
   private String titulo;
   private String descripcion;
   private LocalDate fecha;
   protected double renta; //Protected porque algunas clases hijas necesitan verla para calcular seguro
   private boolean cancelado;
   
   public Evento(String codigo, String titulo, String descripcion, LocalDate fecha, double renta) {
      this.codigo = codigo;
      this.titulo = titulo;
      this.descripcion = descripcion;
      this.fecha = fecha;
      this.renta = renta;
      cancelado = false;
   }

   public String getCodigo() {
      return codigo;
   }

   public void setCodigo(String codigo) {
      this.codigo = codigo;
   }

   public String getTitulo() {
      return titulo;
   }

   public void setTitulo(String titulo) {
      this.titulo = titulo;
   }

   public String getDescripcion() {
      return descripcion;
   }

   public void setDescripcion(String descripcion) {
      this.descripcion = descripcion;
   }

   public LocalDate getFecha() {
      return fecha;
   }

   public void setFecha(LocalDate fecha) {
      this.fecha = fecha;
   }

   public double getRenta() {
      return renta;
   }

   public void setRenta(double renta) {
      this.renta = renta;
   }
   
   public boolean estaCancelado() {
      return cancelado;
   }

   
   public void setCancelar(boolean cancelar) {
      cancelado = cancelar;
   }

   
   @Override
   public boolean equals(Object obj) {
      
      if (obj instanceof Evento) {
         Evento otroEvento = (Evento)obj;
         return otroEvento.codigo.equals(codigo);
      }
      else
         return false;
   }
   
}

Todos estos cambios están en Google Drive
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Demo8v

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 12
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #16 en: 21 de Febrero 2021, 01:18 »
Hola
Justo estaba estudiando el codigo, hoy estuve viendo como conseguir un computador prestado para almenos divisar por mi mismo todo el proyecto y entregar lo que se logro. Por los momento me estoy enfocando en estudiar solo lo que ya esta hecho y que se o almenos espero que no cambie con las necesarias actualizaciones, y por lo de guardar en disco no te preocupes, tengo que adaptarme debido a mi falta de computador porque no puedo trabajar sin eso. Te agradezco nuevamente por tu ayuda
« Última modificación: 21 de Febrero 2021, 01:24 por Demo8v »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 983
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #17 en: 21 de Febrero 2021, 01:28 »
Hola.
Lo ya escrito no creo que cambie apenas a partir de ahora.
Desde luego la parte de gestión de usuarios se puede considerar finalizada.

Las clases Evento, puede que surja algún cambio, según vayamos añadiendo funcionalides al panel de gestión de eventos.

Al cuál por cierto, añado otro detalle que no había tenido en cuenta.
Si el usuario logueado es Limitado, además de no poder gestionar Usuarios, tampoco va a poder hacer gran cosa con los Eventos. Tan solo va a poder visualizarlos.

Así que tenemos que permitirle acceder al panel de gestión de eventos, pero desactivando los botones para las acciones en las que no tiene permisos.

Así que a PanelEventos le añadimos este método:

Código: [Seleccionar]
public void setLimitado(boolean limitado) {
//si limitado es TRUE, los enabled serán FALSE
btNuevo.setEnabled(!limitado);
btCancelar.setEnabled(!limitado);
btEditar.setEnabled(!limitado);
}

Si este método recibe un TRUE, desactivará dichos botones.

Este método será invocado cada vez que se muestre este panel en pantalla, lo hacemos desde el Listener llamado AccionGestionarEventos, que está escrito en la clase principal JavaTicket.
Al invocarlo, comprobamos si el usuario logueado es de clase Limitado, en cuyo caos enviaremos un TRUE a este método.

Citar
   //Acciones para los botones del menu principal
   private class AccionGestionarEventos implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         pnEventos.setLimitado(usuarioLogueado instanceof Limitado?true:false);
         cardLayout.show(panelActivo, "evento");
      }
   }

Y ahora sí, si nos logueamos con un usuario limitado, encontraremos algunos botones inaccesibles.
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Demo8v

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 12
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #18 en: 21 de Febrero 2021, 18:21 »
Buen dia
He logrado conseguir un computador por hoy. He descargado netbeans para correr el programa por mi cuenta, pero de alguna manera no me deja iniciar sesion y me tira consecutivos errores. Creo que es por la manera en la que ingreso los datos descargados ya que no se como importar o exportar projectos desde netbeans, intente viendo videos de youtube pero no lo consegui.

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 983
    • Ver Perfil
Re: Ayuda con mi proyecto!
« Respuesta #19 en: 21 de Febrero 2021, 19:13 »
Hmmm, mi proyecto está hecho bajo Eclipse. No se si NetBeans tendrá opción para importar proyecto desde Eclipse.

En cualquier caso, crea un nuevo proyecto llamado JavaTicket.
Dentro de ese proyecto, crea 4 packages con los nombres:
eventos, gui, img, usuarios

Ahí puedes copiar las clases del archivo zip desde el explorador de Windows a los packages de NetBeans.
Trata de replicar esta estructura:



Incluso quizás puedas copiar directamente las carpeta del zip sin crear previamente packages.
Un package en realidad, es una carpeta como otra cualquiera.

NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".