A ver, alguna pequeña mejora.
El menú mejor meterlo dentro del bucle while, así se muestra siempre después de cada acción.
De lo contrario, solo se muestra una vez
void estructuraMenu(){
Scanner leer=new Scanner(System.in);
gestionPaciente datos=new gestionPaciente();
gestionHorario info = new gestionHorario(datos);
int op;
boolean Salir=false;
while(!Salir){
System.out.println("\nMenú de acciones");
System.out.println("1. Registrar nuevo paciente");
System.out.println("2. Agendar Cita (Ya sea nuevo o no el paciente)");
System.out.println("3. Mostrar datos del Paciente");
System.out.println("4. Mostrar datos de la Cita");
System.out.println("4. Eliminar cita");
System.out.println("6. Salir");
try {
System.out.println("¿Cuál acción desea realizar?");
op=leer.nextInt();
switch (op){
Sobre el caso 2.
Yo lo que detecto al indicar 'N' es que el Scanner se salta la lectura de la cita;
if(op=='N'){
System.out.println("Introduzca el ID de la cita");
String cita=leer.nextLine();
Y eso se debe a que anteriormente, se ha hecho una lectura con next()
public boolean nuevo() {
char op;
System.out.println("¿Es nuevo el paciente?(S/N)");
do{
op=leer.next().charAt(0);
next() debería usarse solo en caso concretos (yo de hecho no lo uso prácticamente nunca), porque no hace una lectura "completa" de lo que ha entrado por teclado.
next() devuelve lo "siguiente" que se pueda considerar una palabra o una letra, pero deja en el buffer de entrada cosas como el caracter "retorno de carro", que es un carácter especial que generamos cada vez que pulsamos la tecla enter/intro para introducir un dato.
¿Problema?
Que si luego queremos hacer una lectura con nextLine(), este método si retorna TODO lo que se encuentre en el buffer. Entonces, si al momento de invocarlo se encuentra con que el buffer de entrada ya tiene un carácter de "retorno de carro" disponible, entonces nextLine() piensa que el usuario ya ha terminado de introducir el dato, pero no es cierto.
Por eso, al menos a mi me ocurre, se me salta la lectura del ID de la cita y pasa a la del paciente, sin que yo haya podido teclear nada.
Vuelva a introducir el dato correcto.
n
Vuelva a introducir el dato correcto.
N
Introduzca el ID de la cita
Inroduce el ID del paciente
2
Esto se soluciona haciendo siempre lecturas con nextLine(), así las lecturas son "completas" y no se dejan restos que luego puedan falsear lecturas posteriores.
A partir de ahí, al introducir id de paciente, nos encontramos con un error de metodología.
Pedimos el ID, pero no hacemos absolutamente nada con ese dato. Lo siguiente que se hace es llamar al método mostrar() del gestor de pacientes, que lo que hace es pedir de nuevo el id mediante un JOptionPane.
if(op=='N'){
System.out.println("Introduzca el ID de la cita");
String cita=leer.nextLine();
System.out.println("Inroduce el ID del paciente");
String id=leer.nextLine();
pacientes.mostrar();
Por cierto, según el programa que estés usando para ejecutar el código, puede que no veas el JOptionPane porque se queda por detrás del programa. Esto ocurre también con los otros case del switch.
A mí me pasa usando Eclipse, parece que al llegar a ese punto la aplicación no está haciendo nada, pero en realidad ha salido un JOptionPane que para verlo tengo que minimizar Eclipse.
Pero supongo que no necesitamos que nos muestren ningún paciente, si no que nos retornen uno a partir del ID.
Y con el paciente y los otros datos, debemos crear una cita, bueno, lo que tu has llamado como clase
Horarios.
Pero veo que en esta clase (donde por cierto los métodos setter están mal), has comentado las líneas relativas al paciente:
public class Horarios {
private String hora,fecha,cita;
// private gestionPaciente paciente;
public Horarios(String fecha, String hora, String cita){
this.hora=hora;
this.fecha=fecha;
this.cita=cita;
//this.paciente=paciente;
}
String getFecha(){
return fecha;
}
void setfecha(){
this.fecha=fecha;
}
String getHora(){
return hora;
}
void setHora(){
this.hora=hora;
}
String getCita(){
return cita;
}
void setCita(){
this.cita=cita;
}
// gestionPaciente getPac(){
// return paciente;
//}
//void setPac(){
// this.paciente=paciente;
//}
public void mostrar(){
System.out.println("\n\t---------------");
System.out.println("HORARIO");
System.out.println("ID Cita: ");
System.out.println(cita);
System.out.println("Fecha: ");
System.out.println(fecha);
System.out.println("Hora: "+hora);
System.out.println("\t---------------");
}
}
¿Por qué? ¿No se debe incluir al paciente en la cita?
¿Cómo sabemos luego a cuál paciente corresponde cada cita agendada?
Creo que lo correcto es que sí esté incluido, pero no un
gestionPaciente, si no
un datosPacientes, que es la clase que representa a un paciente en concreto.
Quedaría así la clase
Horarios(con setters corregidos)
public class Horarios {
private String hora,fecha,cita;
private datosPacientes paciente;
public Horarios(String fecha, String hora, String cita, datosPacientes paciente){
this.hora=hora;
this.fecha=fecha;
this.cita=cita;
this.paciente=paciente;
}
public String getFecha(){
return fecha;
}
public void setfecha(String fecha){
this.fecha=fecha;
}
public String getHora(){
return hora;
}
public void setHora(String hora){
this.hora=hora;
}
public String getCita(){
return cita;
}
public void setCita(String cita){
this.cita=cita;
}
public datosPacientes getPac(){
return paciente;
}
public void setPac(datosPacientes paciente){
this.paciente=paciente;
}
public void mostrar(){
System.out.println("\n\t---------------");
System.out.println("HORARIO");
System.out.println("ID Cita: ");
System.out.println(cita);
System.out.println("Fecha: ");
System.out.println(fecha);
System.out.println("Hora: "+hora);
System.out.println("Paciente: " + paciente.nom);
System.out.println("\t---------------");
}
}
Y ahora, en el case 2 donde agendamos las citas, podemos usar nextLine() para las lecturas de Strings y caracteres char (además nos permite transformar lo tecleado a mayúsculas) y también rediseñar los condicionales IF, con IF ELSE... para quede un poco más elegante.
Cuando se introduzca N para indicar que el paciente ya existe, debemos pedir el ID y que el gestor de pacientes nos retorne el paciente correspondiente.
Y con ese paciente creamos el objeto
Horarios.
El método que nos retorna el paciente según el ID, si no encuentra el paciente nos va a retornar null. Esto estaría bien controlarlo, pero para no complicar más el código, yo de momento lo dejaría sin controlar, y en todo caso, cuando ya todo funcione y se tenga más clara la lógica que se está siguiendo, entonces se pueden mejorar estos detalles.
Pero, ¿y cuando se introduce S? Hay que crear un paciente nuevo, pero además necesitamos tenerlo a mano para crear el objeto
Horarios.
El paciente se crea DENTRO del método
pacientes.nuevo(), pero FUERA de él, que es donde nos encontramos en el momento en que lo llamamos, no nos va a quedar nada para identificar al paciente que se acaba de crear: ni el id, ni el nombre, ni nada...
Es decir, en la línea que marco en rojo, se ha creado un paciente, pero en las siguientes líneas no tenemos nada para encontrar el paciente que se acaba de crear, y lo necesitamos para agendar la cita en el objeto
Horariosif(op=='S'){
System.out.println("Introduzca el ID de la cita");
String cita=leer.next();
leer.nextLine();
pacientes.nuevo();
System.out.println("Introduzca la hora:");
String hora=leer.nextLine();
System.out.println("Introduzca la fecha (dd/mm/aa)");
String fecha=leer.nextLine();
Horarios nuevo=new Horarios(cita,hora,fecha);
horas.add(nuevo);
Para solucionarlo y agilizar el código, podemos cambiar el método que crea pacientes.
Ahora mismo es de tipo boolean, devuelve true o false, y la verdad es que no estamos dando uso a ese boolean. No nos aporta nada.
Podemos cambiarlo, y hacer que una vez creado el paciente, además de guardarlo nos lo retorne. Así podemos recogerlo y usarlo para agendar la cita.
En la clase gestionPaciente, cambiamos el método nuevo():
public datosPacientes nuevo() {
System.out.println("\n\t NUEVO PACIENTE");
System.out.println("Introduzca ID: ");
String id=leer.next();
System.out.println("Ingrese el nombre: ");
String nom=leer.next();
leer.nextLine();
System.out.println("Ingrese el domicilio: ");
String dir=leer.next();
leer.nextLine();
System.out.println("Ingrese el número de telefono: ");
String telPac=leer.next();
leer.nextLine();
System.out.println("Ingrese el número celular: ");
String celPac=leer.next();
System.out.println("Ingrese el correo electrónico: ");
String corr_ele=leer.next();
System.out.println("Ingrese la edad: ");
int ed=leer.nextInt();
leer.nextLine();
datosPacientes nuevoPaciente =new datosPacientes( nom, telPac, celPac,
corr_ele, dir, id, ed);
pacientes.add(nuevoPaciente);
return nuevoPaciente; //Retornamos el paciente recién creado
}
Así, al crear un paciente nuevo cuando agendamos cita, recibimos el paciente creado para poder dárselo al objeto
HorariosEn la clase
gestionHorario, aplicamos todos estos cambios al método nuevo():
public void nuevo() {
char op;
System.out.println("¿Es nuevo el paciente?(S/N)");
do{
op=leer.nextLine().toUpperCase().charAt(0);
if(op=='S'){
System.out.println("Introduzca el ID de la cita");
String cita=leer.next();
leer.nextLine();
datosPacientes paci = pacientes.nuevo();//Se crea un paciente y nos lo retornan
System.out.println("Introduzca la hora:");
String hora=leer.nextLine();
System.out.println("Introduzca la fecha (dd/mm/aa)");
String fecha=leer.nextLine();
Horarios nuevo=new Horarios(cita,hora,fecha,paci);
horas.add(nuevo);
}
else if(op=='N'){
System.out.println("Introduzca el ID de la cita");
String cita=leer.nextLine();
System.out.println("Introduzca el ID del paciente");
String idPaci = leer.nextLine();
datosPacientes paci = pacientes.getPac(idPaci); //No estamos controlando si retorna null
System.out.println("Introduzca la hora:");
String hora=leer.nextLine();
System.out.println("Introduzca la fecha (dd/mm/aa)");
String fecha=leer.nextLine();
Horarios nuevo=new Horarios(cita,hora,fecha,paci);
horas.add(nuevo);
}
else
System.out.println("Vuelva a introducir el dato correcto.");
}while((op!='S')&&(op!='N'));
}
Ahora ya podemos agendar citas, sin embargo, todavía hay un error.
Si pedimos que se muestren las citas agendadas (recuerda que el JOptionPane se queda escondido detrás de tu editor de código), falla al encontrar citas buscando por el id de la cita.
Y es porque al construir los objetos Horarios, no estamos dando los parámetros en el orden correcto.
Para crearlos estamos dando el id de la cita, la hora, la fecha y el paciente:
Horarios nuevo=new Horarios(cita,hora,fecha,paci);
Pero en su clase, el constructor lo hemos definido con un orden distinto.
Primero la fecha, luego la hora, luego el id de la cita y finalmente el paciente
public Horarios(String fecha, String hora, String cita, datosPacientes paciente)
Hay que construir los
Horarios dandole los datos en el mismo orden que hemos establecido en el constructor, si no, los valores de los atributos están intercambiados unos con otros y por eso ahora no se encuentran citas por el id de cita.
Hay que corregirlo:
Horarios nuevo=new Horarios(fecha,hora,cita,paci);
Y con esto, ya parece funcionar más o menos todo bien.
Habrá cosas y detalles por pulir, por ejemplo, al eliminar una cita el mensaje que se muestra en pantalla es que se ha eliminado un paciente y no una cita
public boolean eliminar(){
String cita=JOptionPane.showInputDialog(null,"Introduzca identificador de la cita para mostar datos: ",
"Mostrar datos de la cita",JOptionPane.QUESTION_MESSAGE);
Horarios citas=null;
for (int i=0;i<horas.size();i++){
if(horas.get(i).getCita().equals(cita)){
citas=horas.remove(i);
}
}
if(citas==null){
JOptionPane.showMessageDialog(null, "No se encuentra ninguna cita con el ID:\n"+cita,
"Cita no encontrada", JOptionPane.WARNING_MESSAGE);
return false;
}else {
JOptionPane.showMessageDialog(null, "Se elimino el paciente con ID:\n" + cita,
"Paciente Eliminado", JOptionPane.INFORMATION_MESSAGE);
return false;
}
}
Pero son detalles para ir puliendo poco a poco.
Sobre todo recuerda que cuando al elegir una opción parezca que el programa no hace nada, seguramente es que ha aparecido un JOptionPane que se ha quedado detrás del editor de código.
Minimiza el editor, o usa las teclas ALT+TAB para rotar entre las ventanas abiertas.
Si no es obligatorio usar los JOptionPane, yo lo quitaría y lo haría todo por la consola de texto.
Un saludo.