Autor Tema: programa java reservas sala cine interfaz gráfica Swing compra de boletos código  (Leído 9387 veces)

Anonimuxx 30167832

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 9
    • Ver Perfil
Hola, tengo que resolver este ejercicio en Java sobre una sala de cine. Agradezco ayuda.

La sala de cine se debe visualizar en la interfaz, por lo tanto, usted determina cual es la manera más oportuna de representarla; por ejemplo, utilizando una tabla, botones o entre otros.

• La sala de cine cuenta con 72 asientos (8 filas y 9 columnas), en donde cada silla de la sala debe estar representada por un número consecutivo y una letra.

• Aleatoriamente reserve 25 espacios, los cuales estarán bloqueados y los mismos deben estar representados en la interfaz de alguna manera. Así mismo, si algunos usuarios han comprado boletos, esos asientos deben estar bloqueados también.

• Mientras que el sistema se esté ejecutando, la matriz que se generó debe permanecer activa; es decir, hasta que el sistema se cierre del todo, eventualmente se podría generar otra matriz con otros espacios reservados.

Pantalla

8A 8B 8C 8D 8E 8F 8G 8H 8I
7A 7B 7C 7D 7E 7F 7G 7H 7I
6A 6B 6C 6D 6E 6F 6G 6H 6I
5A 5B 5C 5D 5E 5F 5G 5H 5I
4A 4B 4C 4D 4E 4F 4G 4H 4I
3A 3B 3C 3D 3E 3F 3G 3H 3I
2A 2B 2C 2D 2E 2F 2G 2H 2I
1A 1B 1C 1D 1E 1F 1G 1H 1I


Los precios en la sala de cine pueden variar, entre más alejado de la pantalla tienen un valor más alto, caso contrario con los asientos más cercanos; por lo cual, para los asientos de la fila 1 a la 4 el precio por asiento es de 5000 colones, y para los asientos de la fila 5 a la 8 son de 3000 colones. Por lo anterior, imprima la información de los precios al usuario para que sea de su conocimiento

La compra de boletos del cine funciona de la siguiente manera:

1. Usted decide si la compra de boletos está en la misma interfaz de la sala de cine o en otra.

2. Debe solicitar al usuario que ingrese el número de cédula, si la persona está registrada lo debe dejar continuar la compra (se lee desde el archivo), en caso contrario indique que debe colocar un número de cédula válido, o sea, que esté registrado.

3. Ahora, solicite al usuario que elija los asientos que desea reservar, considerando las siguientes acciones:

a. El usuario debe colocar los números de campos que desea adquirir, por ejemplo: 4D, 4E, 4F.

b. Considere que una misma persona, no puede adquirir más de 5 campos en la compra.

c. Una persona que compra boletos, indiferentemente de la cantidad, no puede volver a comprar más.

d. Si elije uno o más campos que ya están ocupados (los que están en bloqueados, ya sea porque se generaron aleatoriamente o porque otros usuarios han comprado), debe indicarle que no los puede reservar. Automáticamente esos campos se bloquean en la sala de cine en caso de que otra persona ingrese a comprar ya no estarían
disponibles.

e. En la interfaz también debe aparecer el monto total a pagar por los asientos seleccionados.

4. Una vez que se dio el proceso de compra de boletos, guarde la siguiente información en un archivo: cédula, nombre y género de la persona, además, los asientos seleccionados, el monto total a pagar, así como la fecha y hora del sistema en el momento de la compra. Por ejemplo: 201400144, Alejandro, Masculino, 4D, 4E, 4F, 15000, 08/03/2021 – 11:30 AM.

¿Alguien me puede ayudar por favor?  :'(
« Última modificación: 09 de Mayo 2021, 20:29 por Ogramar »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
Re: ayuda con este ejercicio plss
« Respuesta #1 en: 14 de Marzo 2021, 13:55 »
Hola.

Para representar gráficamente los asientos puedes escribir una clase que herede de JLabel.
Así la puedes programar para que tenga atributos como por ejemplo indicar si está reservado o no dicho asiento (con un boolean) o indicar el valor del importe a pagar para reservar ese asiento en concreto.

Cada asiento, como hereda de JLabel y por tanto es en realidad una etiqueta, podrá mostrar el texto con el código de asiento asignado: 1A, 2C, etc..
Puedes añadirle un borde con algo de grosor y colorearlo, al igual que el texto, con distinto color según si un asiento está reservado o no.
Así visualmente en seguida se sabe que asientos están disponibles.

Esta podría ser la clase Asiento, que en realidad es un JLabel.
Como métodos tiene uno para informar si está reservado o no y otro para la acción de reservar el asiento, que consiste en cambiar el valor del boolean y el color de texto y borde.

Código: [Seleccionar]
import java.awt.Color;
import java.awt.Font;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.SwingConstants;

public class Asiento extends JLabel{

private boolean reservado;
public final int VALOR;

public Asiento(String nombre, int valor) {
super(nombre);
VALOR = valor;
reservado = false;
setHorizontalAlignment(SwingConstants.CENTER);
setFont(new Font("Verdana", Font.BOLD, 20));
setOpaque(true);
setBackground(Color.WHITE);
setForeground(new Color(16, 175, 5));
setBorder(
BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(5,5,5,5, new Color(16,175,5)),
BorderFactory.createEmptyBorder(10, 10, 10, 10)));
setToolTipText("Disponible, valor: " + VALOR);
}

public boolean estaReservado() {
return reservado;
}

public void reservar() {
reservado = true;
setForeground(Color.RED);
setToolTipText("Reservado");
setBorder(null);
setBorder(
BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(5, 5, 5, 5, Color.RED),
BorderFactory.createEmptyBorder(10, 10, 10, 10)));
}

}

Bien, para mostrar estos asientos de forma similar a la que pide el enunciado, se puede crear una clase JPanel que se encargue de mostrarlos.
Esta clase tendrá una matriz de 8x9 con los 72 objetos de la clase Asiento escrita anteriormente.
Para mostrarlos en pantalla, se puede usar un GridLayout. A este gestor le podemos pedir que forme una "grilla", también de 8x9, para mostrar los Asientos en pantalla.

Esta clase además tendría métodos para gestionar los asientos.
Uno para iniciar la matriz de Asientos, con sus correspondientes código de asiento y valor de reserva.
Otro método se encargaría de hacer 25 reservas al azar, ya que así lo pide el enunciado.

Y otro más que reciba un String con un código de asiento para comprobar si está disponible.
Podemos hacer que si está disponible, retorne una referencia de dicho asiento y ya desde otro punto del programa haremos con él lo que haya que hacer.
Si no está disponible porque está reservado, o porque nos han dado un código que no existe, se informa en pantalla y se retorna valor null.

Código: [Seleccionar]
import java.awt.GridLayout;
import java.util.Random;

import javax.swing.BorderFactory;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class PanelAsientos extends JPanel{

private Asiento[][] asientos;

public PanelAsientos() {
iniciarAsientos();

setLayout(new GridLayout(8,9,4,4));
for(int i = 0; i < 8; i++)
for(int j = 0; j < 9; j++)
add(asientos[i][j]);

setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(15,15,15,15),
BorderFactory.createTitledBorder("Asientos de la sala")),
BorderFactory.createLoweredSoftBevelBorder()));
}

private void iniciarAsientos() {
asientos = new Asiento[8][9];
int nAsiento = 8;
for (int i = 0; i < 8; i++) {
int valor;
if (i < 4) //Valor depende de la posicion de las filas de asientos
valor = 3000;
else
valor = 5000;
asientos[i][0] = new Asiento(nAsiento+"A", valor);
asientos[i][1] = new Asiento(nAsiento+"B", valor);
asientos[i][2] = new Asiento(nAsiento+"C", valor);
asientos[i][3] = new Asiento(nAsiento+"D", valor);
asientos[i][4] = new Asiento(nAsiento+"E", valor);
asientos[i][5] = new Asiento(nAsiento+"F", valor);
asientos[i][6] = new Asiento(nAsiento+"G", valor);
asientos[i][7] = new Asiento(nAsiento+"H", valor);
asientos[i][8] = new Asiento(nAsiento+"I", valor);
nAsiento--;
}

reservasAzar();
}

private void reservasAzar() {
int reservas = 25;
Random azar = new Random();
while(reservas > 0) {
int fila = azar.nextInt(8);
int columna = azar.nextInt(9);
if (!asientos[fila][columna].estaReservado()) {
asientos[fila][columna].reservar();
reservas--;
}

}
}

public Asiento compruebaAsiento(String asiento) {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 9; j++)
if (asientos[i][j].getText().equals(asiento)) {
if (asientos[i][j].estaReservado()) {
JOptionPane.showMessageDialog(null, asiento + " ya está reservado",
"Reservar asientos", JOptionPane.WARNING_MESSAGE);
return null;
}
else
return asientos[i][j];
}
}
//Si los bucles finalizan sin que haya habido un return, es que este asiento no existe
JOptionPane.showMessageDialog(null, "No existe el asiento: " + asiento,
"Reservar asientos", JOptionPane.WARNING_MESSAGE);
return null;
}

}

Bien, con esto en principio ya tendríamos la parte necesaria para crear y mostrar Asientos en pantalla.
Pero esto es solo una parte.

El enunciado dice que se ha de validar el acceso de usuarios pidiendo una cédula y comprobar si está registrada.
Además, de estos usuarios hay que saber nombre y género.
Así que lo primero sería crear una clase Usuario con estos atributos.
Como métodos, nos va a bastar con un getter para la cédula y sobreescribir el método toString() para obtener todos sus datos en una sola línea String, ya que luego tendremos que guardarlos en un fichero de texto cuando el usuario haga reservas.

Como no se pide crear una opción para registrar usuarios, si no que se da por hecho que el programa ya comienza con algunos usuarios registrados, a esta misma clase podemos incluirle un método estático que nos devuelva un arreglo con algunos Usuarios ya preconfigurados.
Así luego no es necesario hacer ningún tipo de registro.

Código: [Seleccionar]
public class Usuario {

private String cedula;
private String nombre;
private String genero;

public Usuario(String cedula, String nombre, String genero) {
this.cedula = cedula;
this.nombre = nombre;
this.genero = genero;
}

public String getCedula() {
return cedula;
}

@Override
public String toString() {
return String.format("%s, %s, %s", cedula, nombre, genero);
}

/*
* Método para obtener rápidamente usuarios de prueba
*/
public static Usuario[] fabricaUsuarios() {
Usuario[] usuarios = new Usuario[10];
usuarios[0] = new Usuario("201400144", "Alejandro", "Masculino");
usuarios[1] = new Usuario("209061239", "Sara", "Femenino");
usuarios[2] = new Usuario("200861295", "Luis", "Masculino");
usuarios[3] = new Usuario("208716283", "Laura", "Femenino");
usuarios[4] = new Usuario("209061294", "Javier", "Masculino");
usuarios[5] = new Usuario("208529871", "Eva", "Femenino");
usuarios[6] = new Usuario("207272100", "Pablo", "Masculino");
usuarios[7] = new Usuario("208619651", "Teresa", "Femenino");
usuarios[8] = new Usuario("202907086", "Manuel", "Masculino");
usuarios[9] = new Usuario("204208715", "Diana", "Femenino");
return usuarios;
}

}

Teniendo esta clase Usuario, ahora hay que decidir cómo queremos hacer el proceso de validación y posterior reserva.

Para simplificarlo, se podría crear un JFrame donde en la parte central se visualicen los asientos (mediante la clase PanelAsientos que escribimos antes).
Debajo de este panel, se puede usar un panel "contenedor" que contenga a su vez a dos paneles.
Uno con un campo de texto para pedir cédula y un botón para validar usuario.
Otro también con un campo de texto para pedir los asientos que se quieren reservar y dos botones, uno para validar la reserva y otro para salir sin reservar nada.
Estos paneles no se mostrarían a la vez, si no que irían alternandose. Primero se muestra el panel para hacer "login de usuario" y si introducen una cédula registrada, se cambia al panel para hacer reservas. Cuando termina el proceso de reserva, vuelve a mostrarse el panel "login".

Vamos a escribir primero la clase del panel para pedir cédula.
Sería muy sencilla, solo ha de mostrar un JLabel, el campo de texto y el botón de validación. Podemos usar un BoxLayout vertical para acomodar estos tres elementos.

Como métodos, necesitaríamos dos, uno que retorne el contenido del campo de texto (la comprobación de la cédula la haríamos en otro sitio) y un método para resetear el panel, que consiste en eliminar el texto del campo.
Código: [Seleccionar]
import java.awt.Font;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class PanelLogin extends JPanel{

private JTextField campoCedula;
public JButton btAcceder;

public PanelLogin() {
campoCedula = new JTextField(16);
campoCedula.setFont(new Font("Verdana", Font.PLAIN, 16));
btAcceder = new JButton("Acceder");
btAcceder.setFont(new Font("Verdana", Font.PLAIN, 18));

JPanel pnSuperior = new JPanel();
JLabel etiq = new JLabel("Solo usuarios registrados. Introduzca su cédula");
etiq.setFont(new Font("Verdana", Font.BOLD, 16));
pnSuperior.setLayout(new BoxLayout(pnSuperior, BoxLayout.Y_AXIS));
JPanel pnEtiq = new JPanel();
pnEtiq.add(etiq);
pnSuperior.add(pnEtiq);
JPanel pnCampo = new JPanel();
pnCampo.add(campoCedula);
pnSuperior.add(pnCampo);
pnSuperior.setBorder(new EmptyBorder(15,15,15,15));

JPanel pnBoton = new JPanel();
pnBoton.add(btAcceder);
pnBoton.setBorder(new EmptyBorder(15,15,15,15));

setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(pnSuperior);
add(new JSeparator());
add(pnBoton);
}

public String getCedula() {
return campoCedula.getText();
}

public void reset() {
campoCedula.setText(null);
}

}


Y ahora podemos escribir el otro panel para solicitar reservas.
Sería muy parecido a este anterior, un JLabel, un campo de texto y un par de botones.
Y métodos, igual que el anterior, uno para resetear el campo de texto y otro para que retorne lo que haya tecleado el usuario, para ser procesado en otra parte del programa.

Código: [Seleccionar]
import java.awt.Font;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class PanelReservar extends JPanel{

private JTextField campoReservas;
public JButton btReservar;
public JButton btVolver;

public PanelReservar() {
campoReservas = new JTextField(16);
campoReservas.setFont(new Font("Verdana", Font.PLAIN, 16));
btReservar = new JButton("RESERVAR");
btReservar.setFont(new Font("Verdana", Font.PLAIN, 18));
btVolver = new JButton("Volver");
btVolver.setFont(new Font("Verdana", Font.PLAIN, 18));

JPanel pnSuperior = new JPanel();
JLabel etiq = new JLabel("Indique códigos de asiento separados por comas (max 5 reservas)");
etiq.setFont(new Font("Verdana", Font.BOLD, 16));
pnSuperior.setLayout(new BoxLayout(pnSuperior, BoxLayout.Y_AXIS));
JPanel pnEtiq = new JPanel();
pnEtiq.add(etiq);
pnSuperior.add(pnEtiq);
JPanel pnCampo = new JPanel();
pnCampo.add(campoReservas);
pnSuperior.add(pnCampo);
pnSuperior.setBorder(new EmptyBorder(15,15,15,15));

JPanel pnBotones = new JPanel();
pnBotones.setLayout(new BoxLayout(pnBotones, BoxLayout.X_AXIS));
JPanel pnIzq = new JPanel();
pnIzq.add(btReservar);
JPanel pnDer = new JPanel();
pnDer.add(btVolver);
pnBotones.add(pnIzq);
pnBotones.add(pnDer);
pnBotones.setBorder(new EmptyBorder(15,15,15,15));

setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(pnSuperior);
add(new JSeparator());
add(pnBotones);
}

public String getReservas() {
return campoReservas.getText().toUpperCase();
}

public void reset() {
campoReservas.setText(null);
}

}

En estos dos paneles, lo botones JButton serán declarados como public para que luego sea más sencillo asignarles a cada uno los ActionListener que les darán funcionalidad.

Bien, pues ya tendríamos todos los elementos necesarios para crear la clase principal, donde se maquetaría el JFrame con todo esto y escribiríamos la lógica de las acciones de los botones.
Esto lo vemos 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: 988
    • Ver Perfil
Re: ayuda con este ejercicio plss
« Respuesta #2 en: 14 de Marzo 2021, 14:50 »
Para el JFrame principal podemos usar un BorderLayout.
En el centro colocaremos el panel que muestra los asientos.

Debajo, en la parte "sur", estaría el panel "contenedor" que iría alternando entre los paneles de "login" y el de validación de reservas.
Para hacer que alterne entre uno y otro, usaremos el CardLayout.

Luego además, arriba en la parte "norte", podemos incluir un botón de "ayuda" que muestre los datos de los usuarios registrados.
Para probar el programa hay que introducir cédulas de usuarios registrados, para no tener que mirar el código para ver que cédulas se pueden usar, incluimos ese botón para mostrar en pantalla directamente la lista de usuarios registrados y así enseguida vemos que cédulas podemos usar.

Entre los atributos, tenemos un ArrayList con los Usuario de prueba ya registrados.
Los he puesto en un ArrayList, y no en un arreglo tal y como los habíamos creado en la clase Usuario, porque el enunciado pide que cuando un usuario ha hecho reserva, ya no puede hacer más compras. Así que para controlar esto, lo más rápido es eliminar a este usuario de la lista de registrados y así no puede volver a validarse.
Y para eliminar usuarios de una lista, es más fácil con ArrayList.

Otro atributo es una referencia al "usuario activo", es decir, el usuario que ha validado su cédula y se dispone a hacer reservas.
Tenerlo aquí referenciado es muy cómodo para luego enviar sus datos al fichero de texto y también para saber a quien hay que eliminar del ArrayList cuando haya hecho su compra.

Muestro primero los atributos de esta clase y su constructor donde se ve como se maqueta todo esto que he comentado:
Código: [Seleccionar]
public final class Cine extends JFrame{
private ArrayList<Usuario> usuarios;
private Usuario usuarioActivo;
private PanelAsientos asientos;
private PanelLogin pnLogin;
private PanelReservar pnReservar;
private CardLayout grupoPaneles;
private JPanel pnSur;
private JButton btCedulas;

public Cine() {
usuarios = new ArrayList<Usuario>(Arrays.asList(Usuario.fabricaUsuarios()));
asientos = new PanelAsientos();

pnReservar = new PanelReservar();
pnReservar.btReservar.addActionListener(new AccionReservar());
pnReservar.btVolver.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
pnReservar.reset();
pnLogin.reset();
grupoPaneles.first(pnSur); //Volvemos a mostrar panel login
}
});

pnLogin = new PanelLogin();
pnLogin.btAcceder.addActionListener(new AccionLogin());
pnSur = new JPanel();
grupoPaneles = new CardLayout();
pnSur.setLayout(grupoPaneles);
pnSur.add(pnLogin, "login");
pnSur.add(pnReservar, "reservar");

JPanel pnNorte = new JPanel();
btCedulas = new JButton("<html><p style=\"text-align: center\">AYUDA<br>Ver cédulas disponibles</p></html>");
btCedulas.setFocusPainted(false);
btCedulas.addActionListener(new AccionVerCedulas());
pnNorte.add(btCedulas);

setLayout(new BorderLayout());
add(pnNorte, BorderLayout.NORTH);
add(asientos, BorderLayout.CENTER);
add(pnSur, BorderLayout.SOUTH);

setTitle("Reservas de Cine");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
pack();
setLocationRelativeTo(null);
setVisible(true);
}

Ahora, en esta misma clase, habría que escribir las clases ActionListener que darán funcionalidad a los botones de la interfaz.
Estos ActionListener es donde se va a contener la lógica del programa, como validar un usuarios, como validar reserva, que hacer si nos han pedido asientos que no existen o están reservados, etc...

El primer ActionListener que podemos ver es el correspondiente al botón "ayuda" del panel norte.
Es muy simple, para mostrar los usuarios registrados, recorremos el ArrayList donde tenemos los usuarios y creamos un String con sus datos para mostrarlos en un JOptionPane:

Código: [Seleccionar]
private class AccionVerCedulas implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
StringBuilder mensaje = new StringBuilder();
for (Usuario usu: usuarios)
mensaje.append(usu + "\n");

JOptionPane.showMessageDialog(null, mensaje, "Cédulas para probar programa",
JOptionPane.INFORMATION_MESSAGE);
}
}


El siguiente ActionListener es para validar el usuario.
Lo que hace es pedir al PanelLogin la cédula que ha introducido el usuario.
Comprueba si existe en el ArrayList de Usuarios, si existe, selecciona al Usuario correspondiente como "usuario activo" y pide al CardLayout que muestre el panel para validar reservas.
Si no existe nadie con esa cédula, se informa en pantalla.

Código: [Seleccionar]
private class AccionLogin implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String cedula = pnLogin.getCedula();
boolean encontrado = false;
for (Usuario usu: usuarios) {
if (usu.getCedula().equals(cedula)) {
encontrado = true;
usuarioActivo = usu;
}
}
if (encontrado)
grupoPaneles.show(pnSur, "reservar");
else
JOptionPane.showMessageDialog(null, "No existe usuario con cédula: " + cedula,
"Acceso Usuarios", JOptionPane.WARNING_MESSAGE);
}
}

A continuación, viene el más importante de todos, la acción para validar reservas.
En la lógica a seguir hay que tener en cuenta que hay un máximo de 5 reservas. El usuario puede solicitar todos los asientos que quiera, pero solo se admite 5 reservas.
Y de estas 5 reservas, puede que todas estén disponibles, puede que solo algunas, puede que ninguna....

Lo primero es pedir a PanelReservas que nos devuelva lo que haya tecleado el usuario.
Si el usuario ha cumplido con el formato, habrá escrito algo como: 1A,3B,4C

De esa cadena, hay que extraer los códigos de asientos, y esto lo hacemos con el método split() de la clase String, a quien podemos pedirle que "corte" la cadena donde encuentre una coma y nos devuelva los "trocitos" en un arreglo.
Cada elemento de este arreglo, tendrá el código de asiento elegido.

Así que pasaremos cada uno de estos códigos a la clase PanelAsientos para que comprueben si está disponible.
De la lista de asientos pedidos, como ya hemos dicho, solo procesaremos los 5 primeros (o menos si ha pedido menos de 5) y de estos asientos, iremos guardando en un ArrayList los que la clase PanelAsientos compruebe que sí están disponibles.

Al finalizar esto, si el ArrayList de asientos validados está vacío (isEmpty()) es que ningún asiento de los solicitados está disponible.
En cambio, si hay asientos validados en el ArrayList, pues ya tenemos los necesario para informar al usuario de cuántos asientos puede reservar y cuál será el valor total.

Así que le informamos y pedimos que lo confirme con un JOptionPane.
Si lo confirma, los asientos elegido pasan a estar reservados y cambiarán de color en la interfaz.
El usuario será eliminado de la lista, ya no podrá hacer más compras.
Y el panel sur de la interfaz, volverá a mostrar el PanelLogin para validar una nueva cédula.

Además, tal y como pide el enunciado, se guardará en un archivo de texto los datos de esa transacción.

Código: [Seleccionar]
private class AccionReservar implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String peticionReservas = pnReservar.getReservas();
String[] reservas = peticionReservas.split(",");
/*
* Comprobamos si existen los asientos solicitados
* y si están reservados o no. Solo se admiten 5 reservas
* máximo. Si ha solicitado más, serán ignoradas.
*/
int limite = (reservas.length > 5)? 5:reservas.length;
//En este arraylist anotamos los asientos solicitados que podrían reservarse
ArrayList<Asiento> reservasValidas = new ArrayList<Asiento>();
for (int i = 0; i < limite; i++) {
Asiento asiento = asientos.compruebaAsiento(reservas[i]);
if (asiento != null)
reservasValidas.add(asiento);
}
if (reservasValidas.isEmpty())
JOptionPane.showMessageDialog(null, "No hay asientos reservables en su petición.\n"
+ "Indique nombres de asientos que se muestren disponibles con color verde",
"Reservar asientos", JOptionPane.INFORMATION_MESSAGE);
else {
//Calculamos importe total de la reserva y pedimos confirmación
StringBuilder reservados = new StringBuilder();
int importe = 0;
for (Asiento asi: reservasValidas) {
reservados.append("[" + asi.getText() + "] ");
importe += asi.VALOR;
}
String confirmacion = String.format("Asientos a reservar: %s\nImporte total: %d\n"
+ "¿Confirmar reserva?", reservados.toString(), importe);
int respuesta = JOptionPane.showConfirmDialog(null, confirmacion,
"Reservar asientos", JOptionPane.YES_NO_OPTION);

if (respuesta == JOptionPane.YES_OPTION) {
//Reservamos asientos
for (Asiento asi: reservasValidas)
asi.reservar();
//Generamos archivo
crearArchivo(reservados.toString(), importe);
//Este usuario, ya no puede hacer mas reservas, lo sacamos de la lista
usuarios.remove(usuarioActivo);
usuarioActivo = null;
//Volvemos a inicio
pnReservar.reset();
pnLogin.reset();
grupoPaneles.first(pnSur);
}
}
}
}

Lo último que falta, son dos métodos.
Uno es el que se encarga de escribir en archivo de texto los datos de cada transacción.
Y el otro es simplemente el método main() que pone todo el programa en marcha.
Código: [Seleccionar]
private void crearArchivo(String reservados, int importe) {
try {
String fecha = String.format("%d/%d/%d", LocalDate.now().getDayOfMonth(),
LocalDate.now().getMonthValue(), LocalDate.now().getYear());

String hora = String.format("%d:%d", LocalTime.now().getHour(), LocalTime.now().getMinute());

BufferedWriter bw = new BufferedWriter(new FileWriter("reservasCine.txt", true));
bw.write(String.format("Usuario: %s\nAsientos reservados: %s\nImporte: %d\nFecha: %s Hora: %s\n",
usuarioActivo, reservados, importe, fecha, hora));
bw.write("\n\t************************\n");
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
}

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


Si ponemos todo esto en marcha, vemos una sencilla interfaz con los asientos disponibles y algunos marcados en rojo que han sido reservados al azar.



Con el botón superior de "ayuda", podemos ver lista de usuarios para saber que cédulas podemos probar.



Abajo podemos validar cédula, y si tiene éxito, el panel inferior cambia para que podemos hacer reservas.
Aquí me pido reservar toda la fila 1 al completo:



Pero como el límite solo son 5 reservas, me ofrece solo los 5 primeros asientos y el importe total para que lo confirme:



Si acepto, volvemos a la pantalla de login y en pantalla se ve como los 5 primeros asientos de la primera fila, ahora están señalizados en color rojo porque han quedado reservados.



Y la transacción con datos del usuario, asientos, importe, fecha y hora... quedan registrados en un archivo de texto:



Y eso es todo.
Pregunta cualquier cosa que no esté clara o no entiendas.

Adjunto un zip en este mensaje con todo el código fuente.
Saludos.
« Última modificación: 20 de Abril 2023, 13:10 por Kabuto »
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

MariAlejandra

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 2
    • Ver Perfil
Hola, buenas, espero que esten bien.
Lo que voy a poner aqui la verdad no es una respueta al problema, lo que pasa es que a mi me pusieron un ejercicio parecido y es el siguiente:

Se necesita implementar una aplicación para Cinema Poli, con el fin de contar con la sistematización del proceso de asignación de los puestos disponibles. De cada silla del cinema se conoce el tipo de silla (general o VIP), el precio de la boleta según el tipo de silla, su estado (ocupada o disponible).

La aplicación debe contar con una interfaz gráfica que le permita al usuario seleccionar la silla para ser ocupada o para dejarla disponible (debe cambiar de color si está ocupada o disponible), la información de las sillas del cinema se debe almacenar en una matriz de objetos de tipo Silla de tamaño 7X6 (7 filas y 6 columnas).

Además, se debe contar con un menú (botones) para genera y mostrar la siguiente información: porcentaje de ocupación del cine, total de dinero recaudado,
número de sillas disponibles según su tipo (general o VIP), qué sillas se encuentran disponibles, especificando la fila y la columna de cada silla en este estado.

Este ejercicio tiene unas especificaciones, y es que junto con el numero de silla debe tener una imagen de esta, 12 de las sillas son VIP, o sea otro color de silla, lo que quiero es que asi mismo como hace el marco verde cuando esta libre y rojo cuando esta reservada pero que igual muestre las imagenes correspondientes.

En lugar de que solo puedan estar los usuarios registrados tambien del la opcion de registrarse para poder comprar los boletos.

La interfaz tiene un banner, asi que todo lo de los botones debe ir abajo o al lado derecho de las sillas y la informacion si la muestre en otra interfaz.

Porfa Ayuda, es muy importante este ejercicio

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
A ver, hagamos un planteamiento nuevo.

Se mostrarán las 72 butacas en pantalla y el usuario podrá hacer click en ellas para reservar, o liberar reservas.

Previamente, el usuario se ha de registar si es nuevo o identificarse si ya está registrado.

Podemos hacer que las butacas cambien entre tres colores distintos.
VERDE = Butaca disponible
ROJO = Butaca reservada, por un cliente DISTINTO al que está logueado en ese momento
AZUL = Butaca reservada, por el cliente ACTUALMENTE logueado.

Así, el cliente no puede interactuar con las casillas rojas.
Solo podrá clickar las verdes para reservar, o las azules para deshacer la reserva.

Podemos estructurar el proyecto en tres packages: vista, modelo y controlador
Un cuarto package podría contener las dos imágenes que usaremos para mostrar las butacas.

Veamos primero el "Modelo".
Primero, la clase Butaca.
Su atributo "tipo" lo controlamos con un simple int que puede variar entre 0(general) y 1(VIP)
De esta forma, nos sirve como índice para seleccionar directamente en un array uno de los dos precios según el tipo.

Con un String le construiremos un id, que será un número de butaca. Este id servirá para mostrarlo en pantalla pero también para hacer que cada Butaca sea única.

Luego un boolean para saber si está libre u ocupada.

Por constructor recibe el id y el tipo. El boolean se inicia como true, ya que al principio del programa todas las butacas estarán libres.
Código: [Seleccionar]
package modelo;

public class Butaca {
//Precios prefijados según tipo de Butaca
private final float[] PRECIOS = {8.5f, 10f};

private String id;
private int tipo; //Tipo Butaca. 0 = General / 1 = VIP
private boolean estaLibre; //True está libre, False está ocupada

public Butaca(String id, int tipo) {
this.id = id;
this.tipo = tipo;
estaLibre = true;
}

public String getId() {
return id;
}

public int getTipo() {
return tipo;
}

public boolean estaLibre() {
return estaLibre;
}

public float getPrecio() {
return PRECIOS[tipo];
}

public void setLibre(boolean esLibre) {
estaLibre = esLibre;
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Butaca) {
Butaca otraBt = (Butaca) obj;
return id.equals(otraBt.id);
}
else
return false;
}
}

Veamos ahora la clase Cliente.
Puesto que nos dicen que los clientes pueden hacer reservas, pero también anularlas, lo más cómodo y rápido para saber que butacas pertenecen a cada cliente es hacer que la clase Cliente tenga un ArrayList con las butacas que vaya reservando.
Así podemos añadir o quitar reservas.

Otros atributo será un número de cedula y su nombre completo para poder dirigirnos a él.
Entre sus métodos habrá uno que se encargue de calcular el importe total de sus reservas
Código: [Seleccionar]
package modelo;

import java.util.ArrayList;

public class Cliente {

private String cedula;
private String nombreCompleto;
public ArrayList<Butaca> reservas;

public Cliente(String cedula, String nombreCompleto) {
this.cedula = cedula;
this.nombreCompleto = nombreCompleto;
reservas = new ArrayList<Butaca>();
}

public String getCedula() {
return cedula;
}
public String getNombreCompleto() {
return nombreCompleto;
}

public void hacerReserva(Butaca bt) {
reservas.add(bt);
}

public void liberarReserva(Butaca bt) {
reservas.remove(bt);
}

public float calculaImporte() {
float total = 0;
for(Butaca bt: reservas)
total += bt.getPrecio();
return total;
}

}

Bueno, en lo que respecta a la parte del "Controlador", podemos crear una clase para gestionar las dos clases del "Modelo" que acabamos de ver.
Esta clase tendrá un ArrayList para poder añadir clientes y una matriz con las 42 butacas divididas entre 6 filas y 7 columnas.

En su constructo, al inicializar cada objeto Butaca, le generamos un identificador concatenando el valor de su fila con el de su columna.
Además, decidiremos cuáles van a ser VIP. Podemos hacer que las centrales, las que están en las filas 2 y 3, sean VIP y el resto normales.
Esto ya que cada uno decida como quiere hacerlo.

Tiene un método para añadir un nuevo cliente, y otro para buscar un cliente mediante su número de cédula y retornarlo en caso de que exista.

También hay un getter para retornar la matriz de butacas al completo. Esto facilitará las cosas luego.
Código: [Seleccionar]
package controlador;

import java.util.ArrayList;

import modelo.*;

public class GestorCine {

private ArrayList<Cliente> clientes;
private Butaca[][] butacas;

public GestorCine() {
clientes = new ArrayList<Cliente>();
butacas = new Butaca[7][6];
//Inicializamos butacas. Filas centrales serán VIP
for(int i = 0; i < 7; i++)
for(int j = 0; j < 6; j++)
if(i == 2 || i == 3) //Filas centrales
butacas[i][j] = new Butaca(String.format("%d%d",i,j), 1);//VIP
else
butacas[i][j] = new Butaca(String.format("%d%d",i,j),0);//General
}

public void nuevoCliente(Cliente cli) {
clientes.add(cli);
}

public Cliente compruebaCliente(String cedula) {
//Comprobamos por cedula si ya existe este cliente
for (Cliente cl: clientes) {
if(cl.getCedula().equals(cedula))
return cl;
}
//Bucle finaliza sin retorna nada, no existe este cliente
return null;
}

public Butaca[][] getButacas() {
return butacas;
}

}

Sobre la "Vista"...
Queremos mostrar la imagen de una butaca, que será distinta según su tipo.
Además queremos rodear cada imagen con un borde de color para distinguir fácilmente las butacas ocupadas de las que están libres.

Vale, pues podemos crear una clase que herede de JPanel y llamarla PanelButaca.
Cada uno de estos paneles, recibirá una referencia a una de las 72 Butacas con la que estará asociada.
Así sabrá qué número de butaca ha de mostrar, cuál color ha de ser su borde en cada momento y también qué imagen ha de mostrar según el tipo de butaca.

El color del borde también lo vamos a gestionar como un atributo más.

Así que a este JPanel le vamos a añadir dos JLabel en vertical.
Uno mostrará el número de butaca y el otro la imagen jpg que corresponda a su tipo de butaca.
Código: [Seleccionar]
package vista;

import java.awt.Color;
import java.awt.Font;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

import modelo.Butaca;

public class PanelButaca extends JPanel {
//Según tipo butaca, se cargará una de las dos imagenes
private final String[] RUTAS_IMAGEN = new String[] {
"img/butaca_general.jpg", "img/butaca_VIP.jpg"
};

private Butaca butaca;
private Color color;

public PanelButaca(Butaca butaca) {
this.butaca = butaca;
color = Color.GREEN;
setBackground(Color.WHITE);

setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
JLabel idButaca = new JLabel(butaca.getId());
idButaca.setFont(new Font("Consolas", Font.BOLD, 18));
idButaca.setForeground(Color.BLUE);
idButaca.setBorder(BorderFactory.createEmptyBorder(3, 3, 0, 20));
add(idButaca);

JLabel lbButaca = new JLabel(new ImageIcon(
this.getClass().getClassLoader().getResource(RUTAS_IMAGEN[butaca.getTipo()])));
lbButaca.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
add(lbButaca);
cambiaBorde(color);
setToolTipText(setTip());
}

public Butaca getButacaAsociada() {
return butaca;
}

public Color getColor() {
return color;
}

private String setTip() {
if (butaca.estaLibre())
return "Precio: " + butaca.getPrecio();
else
return "Ocupada";
}

public void cambiaBorde(Color color) {
this.color = color;
setBorder(BorderFactory.createMatteBorder(10,10,10,10, color));
setToolTipText(setTip());
}

}

Ahora necesitamos otro panel, que contenga a estos 72 PanelButaca, como si fuera la sala de cine, así que se puede llamar PanelSala

También tendrá una matriz de 7x6 para contener los 72 PanelButaca.
Estos PanelesButaca requieren de las otras 72 Butacas del "Modelo" para inicializarse.
Así que por el constructor le haremos llegar la matriz del "Modelo" para poder crear la matriz de la "Vista.

Por constructor también recibirá un MouseListener que será quien le diga a cada PanelButaca cómo ha de comportarse cuando el usuario haga click en ellas.

De momento, le vamos a dar dos métodos.

Uno de ellos recibe como argumento el cliente logueado y se va a encargar de marcar en azul las butacas reservadas por ESTE cliente.
Para ello cotejaremos el ArrayList de reservas que posee este cliente para saber cuáles hay que marcar en azul.

El otro método, se ejecutará cuando el cliente cierre sesión, y lo que hará será repasar todas las butacas y marcarlas en verde o rojo.
El color azul solo estará presente cuando haya un cliente con la sesión abierta.
Código: [Seleccionar]
package vista;

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseListener;

import javax.swing.BorderFactory;
import javax.swing.JPanel;

import modelo.*;

public class PanelSala extends JPanel {

private PanelButaca[][] butacas;

public PanelSala(Butaca[][] listaButacas, MouseListener escuchador) {

butacas = new PanelButaca[7][6];

setLayout(new GridLayout(7,6,2,4));
for (int i = 0; i < 7; i++)
for (int j = 0; j < 6; j++) {
butacas[i][j] = new PanelButaca(listaButacas[i][j]);
butacas[i][j].addMouseListener(escuchador);
add(butacas[i][j]);
}
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(10, 10, 10, 10),
BorderFactory.createBevelBorder(0)));
}

public void mostrarReservasCliente(Cliente cl) {
//Comprobamos cuáles butacas estan reservadas por este cliente
//para marcarlas en azul
for (int i = 0; i < 7; i++)
for (int j = 0; j < 6; j++)
if (cl.reservas.contains(butacas[i][j].getButacaAsociada()))
butacas[i][j].cambiaBorde(Color.BLUE);
}

public void actualizaColorButacas() {
for (int i = 0; i < 7; i++)
for (int j = 0; j < 6; j++)
if (butacas[i][j].getButacaAsociada().estaLibre())
butacas[i][j].cambiaBorde(Color.GREEN);
else
butacas[i][j].cambiaBorde(Color.RED);
}

}

Bien, ¿y como hará login un cliente?
Podemos añadir un panel en la parte inferior de la interfaz con un único botón que servirá para hacer Login y Logout.
Irá acompañado de un JLabel que irá mostrando en todo momento cuántas reservas tiene hechas el cliente y el importe total que suman.
Código: [Seleccionar]
package vista;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class PanelLogin extends JPanel {

public JButton btLogin;
public JLabel mensaje;

public PanelLogin() {
btLogin = new JButton("Login");
JPanel pnBoton = new JPanel();
pnBoton.add(btLogin);

mensaje = new JLabel("Pulsa el botón para iniciar sesión");
JPanel pnMensaje = new JPanel();
pnMensaje.add(mensaje);

setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
add(pnBoton);
add(pnMensaje);

setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(5, 10, 5, 10),
BorderFactory.createBevelBorder(1)));
}

}

En la parte superior, pondremos otro panel con el nombre del cine.
No voy a invertir mucho esfuerzo en esto, con algo simple ya basta.
Código: [Seleccionar]
package vista;

import java.awt.Color;
import java.awt.Font;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class PanelTitulo extends JPanel {

public PanelTitulo(String titulo) {
JLabel lbTitulo = new JLabel(titulo);
lbTitulo.setForeground(Color.MAGENTA);
lbTitulo.setBackground(Color.WHITE);
lbTitulo.setOpaque(true);
lbTitulo.setFont(new Font("Impact", Font.BOLD, 40));
lbTitulo.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEtchedBorder(Color.MAGENTA, Color.CYAN),
BorderFactory.createEmptyBorder(20, 45, 20, 45)));
add(lbTitulo);
}

}

Bien, con estos elementos ya podemos poner en marcha una versión preliminar del programa.
Para ello nos vamos al "controlador" y creamos una clase Main, la principal, que heredará de JFrame. Mostrará la interfaz, comunicará unas clases con otras y aquí escribiremos los Listener que podamos necesitar para cada función del programa.

Sus atributos serán los principales paneles, el gestor del cine y también un objeto Cliente que contendrá al cliente que haya iniciado sesión.
Si no hay ninguna sesión abierta, tendrá valor null.

Escribiremos un ActionListener para el botón de iniciar sesión.
Ahí se puede ver como tendrá dos comportamientos distintos, según si hay una sesión abierta o está cerrada.

También un MouseListener que será él que le haremos llegar a cada uno de los 72 PanelesButaca
Mediante este Listener es con el que el usuario podrá hacer reservas con solo clickar una butaca.
Por tanto, el comportamiento dependerá de si clicka en una casilla verde, azul, o roja.

Es en esta clase donde hay que prestar más atención, pues es donde se decide la mayor parte de la lógica del programa.
Código: [Seleccionar]
package controlador;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import modelo.*;
import vista.*;

public class Main extends JFrame {

private GestorCine gestor;
private PanelSala sala;
private PanelLogin login;
private Cliente cliente;

public Main() {

gestor = new GestorCine();
sala = new PanelSala(gestor.getButacas(), new AccionReservar());
login = new PanelLogin();
login.btLogin.addActionListener(new AccionLogin());
cliente = null;

setLayout(new BorderLayout());
add(new PanelTitulo("Cinema Poli"), BorderLayout.NORTH);
add(sala, BorderLayout.CENTER);
add(login, BorderLayout.SOUTH);

setTitle("Cinema Poli");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}

private class AccionLogin implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {

if (login.btLogin.getText().equals("Login")) {
String cedula = JOptionPane.showInputDialog("Introduzca su cedula:");
cliente = gestor.compruebaCliente(cedula);
if (cliente == null) {
String nombre = JOptionPane.showInputDialog("Complete el nuevo registros con su nombre completo:");
cliente = new Cliente(cedula, nombre);
gestor.nuevoCliente(cliente);
}
JOptionPane.showMessageDialog(null, "Bienvenido " + cliente.getNombreCompleto() +
"\nLas casillas ROJAS indican que la butaca está reservada por otro cliente."
+ "\nLas VERDES indican que están disponibles."
+ "\nLas AZULES son las que tienes reservadas a tu nombre.");
sala.mostrarReservasCliente(cliente);
login.mensaje.setText(String.format("Hola %s. Tienes %d reservas. Import total: %.2f",
cliente.getNombreCompleto(), cliente.reservas.size(), cliente.calculaImporte()));
login.btLogin.setText("Logout");
}
else {
int confirma = JOptionPane.showConfirmDialog(null, "¿Cerrar sesión?", "Logout", JOptionPane.YES_NO_OPTION);
if (confirma == JOptionPane.YES_OPTION) {
cliente = null;
sala.actualizaColorButacas();
login.mensaje.setText("Pulsa el botón para iniciar sesión");
login.btLogin.setText("Login");
}
}
}
}

private class AccionReservar implements MouseListener {

@Override
public void mouseClicked(MouseEvent e) {
if (cliente == null)
JOptionPane.showMessageDialog(null, "Primero ha de iniciar sesión con el boton Login");
else {

PanelButaca bt = (PanelButaca)e.getSource();

if (bt.getButacaAsociada().estaLibre()) {
bt.getButacaAsociada().setLibre(false);
bt.cambiaBorde(Color.BLUE);
cliente.hacerReserva(bt.getButacaAsociada());
login.mensaje.setText(String.format("Hola %s. Tienes %d reservas. Importe total: %.2f",
cliente.getNombreCompleto(), cliente.reservas.size(), cliente.calculaImporte()));
}
else {
//Si no está libre, solo actuamos si su color es azul, porque es una reserva del cliente
//Al hacer click en su reserva, la butaca quedará liberada
if (bt.getColor().equals(Color.BLUE)) {
bt.getButacaAsociada().setLibre(true);
bt.cambiaBorde(Color.GREEN);
cliente.liberarReserva(bt.getButacaAsociada());
login.mensaje.setText(String.format("Hola %s. Tienes %d reservas. Importe total: %.2f",
cliente.getNombreCompleto(), cliente.reservas.size(), cliente.calculaImporte()));
}
}
}
}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
}

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

Si ejecutamos, veremos que podemos iniciar sesión con número de cedula.
Si somos nuevos, el sistema nos registrará.
Si ya estamos registrados, el sistema nos recuerda y nos mostrará las butacas que tenemos reservadas actualmente.

La interfaz no es bonita, pero cumple con su trabajo


Ahora faltaría añadir otro panel con botones para poder consultar las otras cosas que se solicitan
Citar
se debe contar con un menú (botones) para genera y mostrar la siguiente información: porcentaje de ocupación del cine, total de dinero recaudado,
número de sillas disponibles según su tipo (general o VIP), qué sillas se encuentran disponibles, especificando la fila y la columna de cada silla en este estado.

Pero esto tendrá que ser otro día.

Por cierto, adjunto un zip con mis packages del proyecto.
Un saludo.
« Última modificación: 20 de Abril 2023, 21:42 por Kabuto »
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: 988
    • Ver Perfil
Nos faltaban los botones para consultar datos de ocupación, recaudación, etc...

Es sencillo.
Hacemos una nueva clase que herede de JPanel en el package "vista".

Le maquetaremos 4 botones en vertical.
Para poder escribir sus ActionListener en esta misma clase, en lugar de hacerlo en la clase Main, lo que haremos será que por constructor reciba una referencia a la matriz de las butacas, ya que es lo único que se necesita para poder hacer las consultas que nos piden.

Así, teniendo a mano la matriz, en esta misma clase podemos hacer los 4 ActionListener donde cada uno se ocupará de una de las tareas.
Código: [Seleccionar]
package vista;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import modelo.Butaca;

public class PanelBotones extends JPanel {

private MiBoton btOcupacion;
private MiBoton btRecaudacion;
private MiBoton btDisponibilidadTipo;
private MiBoton btListaDisponibles;
private Butaca[][] butacas;

public PanelBotones(Butaca[][] butacas) {

btOcupacion = new MiBoton("Ocupacion");
btOcupacion.addActionListener(new AccionOcupacion());
btRecaudacion = new MiBoton("Recaudacion");
btRecaudacion.addActionListener(new AccionRecaudacion());
btDisponibilidadTipo = new MiBoton("Tipos Disponibles");
btDisponibilidadTipo.addActionListener(new AccionDisponibilidadTipos());
btListaDisponibles = new MiBoton("Lista Disponibles");
btListaDisponibles.addActionListener(new AccionListarDisponibles());
this.butacas = butacas;

setLayout(new GridLayout(4, 1));
add(new PanelBoton(btOcupacion));
add(new PanelBoton(btRecaudacion));
add(new PanelBoton(btDisponibilidadTipo));
add(new PanelBoton(btListaDisponibles));

setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createRaisedSoftBevelBorder(),
BorderFactory.createEmptyBorder(20,20,20,20)));
setBackground(new Color(223, 195, 188));
}

private class PanelBoton extends JPanel {

public PanelBoton(JButton boton) {
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
boton.setAlignmentX(Component.CENTER_ALIGNMENT);
add(Box.createVerticalGlue());
add(boton);
add(Box.createVerticalGlue());
setBackground(new Color(223, 195, 188));
}
}

public class MiBoton extends JButton {
public MiBoton(String txt) {
super(txt);
setFont(new Font("Verdana", Font.PLAIN, 16));
}
}

//Acciones de los botones
private class AccionOcupacion implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {

int ocupadas = 0;

for (int i = 0; i < butacas.length; i++)
for (int j = 0; j < butacas[i].length; j++)
if (!butacas[i][j].estaLibre())
ocupadas++;

float ocupacion = ocupadas * 100 / 42;

JOptionPane.showMessageDialog(null, String.format("Porcentaje de ocupación: %.2f%%", ocupacion));
}
}

private class AccionRecaudacion implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {

float recaudacion = 0;

for (int i = 0; i < butacas.length; i++)
for (int j = 0; j < butacas[i].length; j++)
if (!butacas[i][j].estaLibre())
recaudacion += butacas[i][j].getPrecio();

JOptionPane.showMessageDialog(null, String.format("Total Recaudacion: %.2f$", recaudacion));
}
}

private class AccionDisponibilidadTipos implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {

int general = 0, VIP = 0;

for (int i = 0; i < butacas.length; i++)
for (int j = 0; j < butacas[i].length; j++)
if (butacas[i][j].estaLibre())
if (butacas[i][j].getTipo()==0)
general++;
else
VIP++;

JOptionPane.showMessageDialog(null,
String.format("Disponibilidad por tipos.\nGeneral: %d\nVIP: %d", general, VIP));
}
}

private class AccionListarDisponibles implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {

StringBuilder mensaje = new StringBuilder("Butacas libres.");

for (int i = 0; i < butacas.length; i++) {
mensaje.append("\n");
for (int j = 0; j < butacas[i].length; j++)
if (butacas[i][j].estaLibre())
mensaje.append(butacas[i][j].getId()  + " ");
}

JOptionPane.showMessageDialog(null, mensaje);
}
}

}

Y ahora solo queda agregar este panel a la interfaz de la clase Main
Citar
public class Main extends JFrame {
   
   private GestorCine gestor;
   private PanelSala sala;
   private PanelLogin login;
   private PanelBotones botones;
   private Cliente cliente;
   
   public Main() {
      
      gestor = new GestorCine();
      sala = new PanelSala(gestor.getButacas(), new AccionReservar());
      login = new PanelLogin();
      login.btLogin.addActionListener(new AccionLogin());
      botones = new PanelBotones(gestor.getButacas());
      cliente = null;
      
      setLayout(new BorderLayout());
      add(new PanelTitulo("Cinema Poli"), BorderLayout.NORTH);
      add(sala, BorderLayout.CENTER);
      add(login, BorderLayout.SOUTH);
      add(botones, BorderLayout.EAST);


Y ya tenemos botones funcionando.


Adjunto zip con el código final.
Hay detalles que se pueden pulir, como mejorar el mensaje al listar las butacas disponibles. Si no hay ninguna libre estaría bien que dijera "No hay butacas disponibles" en lugar de salir un lista en blanco.

Pero eso ya que cada uno lo arregle a su gusto.

Un saludo.
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".