Autor Tema: Programa Java de altas, bajas consulta y listado productos menú con JOptionPane  (Leído 14463 veces)

janegg

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 18
    • Ver Perfil
Mi programa sólo hace el primer método, necesito ayuda. Help me pls, tengo las otras clases

Código: [Seleccionar]
public class Productos
{
   private String clave;
   private String nombre;
   private int precio;
   private int existencia;
   private String nombregenerico;//acido
   private int caducidad;
   private String formafarmaceutica;//tabletas, pastillas, jarabe

   
   public Productos(String clave, String nombre, int precio, int existencia, String nombregnerico, int caducidad, String formafarmaceutica)
   {
   this.clave = clave;
   this.nombre = nombre;
   this.precio = precio;
   this.existencia = existencia;
   }
   
   public void setClave(String clave)
   {
      this.clave = clave;
   }
   public String getClave()
   {
      return clave;
   }
   public void setNombre(String nombre)
   {
      this.nombre = nombre;
   }
   public String getNombre()
   {
      return nombre;
   }
   public void setPrecio(int precio)
   {
      this.precio = precio;
   }
   public int getPrecio()
   {
      return precio;
   }
   public void setExistencia(int existencia)
   {
      this.existencia = existencia;
   }
   public int getExistencia()
   {
      return existencia;
   }
   public void setNombregenerico(String nombregenerico)
   {
      this.nombregenerico = nombregenerico;
   }
   public String getNombregenerico()
   {
      return nombregenerico;
   }
   public void setCaducidad(int caducidad)
   {
      this.caducidad = caducidad;
   }
   public int getCaducidad()
   {
      return caducidad;
   }
   public void setFormafarmaceutica(String formafarmaceutica)
   {
      this.formafarmaceutica = formafarmaceutica;
   }
   public String getFormafarmaceutica()
   {
      return formafarmaceutica;
   }
   
}
 ][public class Medicamentos extends Productos
{
   private String nombregenerico; //acido
   private int caducidad;
   private String formafarmaceutica;//tabletas, pastillas, jarabe
   private int concentracion; //500 mg

   public Medicamentos()
   {
      nombregenerico = null;
      caducidad = 0;
      formafarmaceutica = null;
      concentracion = 0;
   }
   
   public void getNombregenerico(String nombregenerico)
   {
      this.nombregenerico = nombregenerico;
   }
   public String setNombregenerico()
   {
      return(nombregenerico);
   }
   public void getCaducidad(int caducidad)
   {
      this.caducidad = caducidad;
   }
   public int setCaducidad()
   {
      return(caducidad);
   }
   public void getFormafarmaceutica(String formafarmaceutica)
   {
      this.formafarmaceutica = formafarmaceutica;
   }
   public String setFormafarmaceutica()
   {
      return(nombregenerico);
   }
   public void getConcentracion(int concentracion)
   {
      this.concentracion = concentracion;
   }
   public int setConcentracion()
   {
      return(concentracion);
   }
}

« Última modificación: 03 de Julio 2018, 21:59 por Ogramar »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
Hola.

Cuando postees código aquí en el foro, es mejor que lo envuelvas entre las etiquetas [ code ] para que quede mejor visualizado.
Basta con que pulses el boton  --> que verás arriba cuando escribes texto en el foro.
Te aparecerán dos etiquetas y dentro de ellas pegas el código para que quede así:
Código: [Seleccionar]
public class Productos
{
   private String clave;
   private String nombre;
   private int precio;
   private int existencia;
   private String nombregenerico;//acido
   private int caducidad;
   private String formafarmaceutica;//tabletas, pastillas, jarabe

   
   public Productos(String clave, String nombre, int precio, int existencia, String nombregnerico, int caducidad, String formafarmaceutica)
   {
   this.clave = clave;
   this.nombre = nombre;
   this.precio = precio;
   this.existencia = existencia;
   }
   
   public void setClave(String clave)
   {
      this.clave = clave;
   }
   public String getClave()
   {
      return clave;
   }
   public void setNombre(String nombre)
   {
      this.nombre = nombre;
   }
   public String getNombre()
   {
      return nombre;
   }
   public void setPrecio(int precio)
   {
      this.precio = precio;
   }
   public int getPrecio()
   {
      return precio;
   }
   public void setExistencia(int existencia)
   {
      this.existencia = existencia;
   }
   public int getExistencia()
   {
      return existencia;
   }
   public void setNombregenerico(String nombregenerico)
   {
      this.nombregenerico = nombregenerico;
   }
   public String getNombregenerico()
   {
      return nombregenerico;
   }
   public void setCaducidad(int caducidad)
   {
      this.caducidad = caducidad;
   }
   public int getCaducidad()
   {
      return caducidad;
   }
   public void setFormafarmaceutica(String formafarmaceutica)
   {
      this.formafarmaceutica = formafarmaceutica;
   }
   public String getFormafarmaceutica()
   {
      return formafarmaceutica;
   }
   
}


Por otra parte, has publicado un par de clases, pero no el programa principal donde supongo habrá algun menu para hacer las altas, bajas, etc...

No podemos ayudarte si no tenemos todas las clases.

Puedes publicarlas aquí o bien puedes comprimirlas en un archivo .zip y adjuntarlas en tu mensaje aqui en el foro.
PAra adjuntar, debajo del cuadro blanco donde escribimos el texto, verás un linea que pone Opciones Adicionales....
Pinchale y tendrás opcion de adjuntar archivos
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

janegg

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 18
    • Ver Perfil
claro claro, aquí están las demas clases :)
Código: [Seleccionar]
import javax.swing.JOptionPane;
import java.io.*;

public class Metodos
{
int p=0;
  public void altas()throws FileNotFoundException,IOException
  {
   String clave;
   String nombre;
   int precio;
   int existencia;
   try{
      File archivo = new File("archiyect.txt");
      FileWriter escribir = new FileWriter(archivo,true);
     
      clave = JOptionPane.showInputDialog("Dame la clave del producto"); //Por cada uno de estos hay que poner try catch?
      nombre = JOptionPane.showInputDialog("Escribe el nombre del producto"); //esto se guarda en el archivo?
      precio = Integer.parseInt(JOptionPane.showInputDialog("Escribe el precio del producto"));
      existencia = Integer.parseInt(JOptionPane.showInputDialog("Cuántos productos hay en existencia"));
     
      escribir.write(clave+"\n");
      escribir.write(nombre+"\n");
      escribir.write(precio +"\n");
      escribir.write(existencia +"\n");
     
      /*Productos p = new Productos (String clave, String nombre, int precio, int existencia, String nombregnerico, int caducidad, String formafarmaceutica);
      p.getClave(a.clave);
      p.getNombre(a.nombre);
      p.getPrecio(a.precio);
      p.getExistencia(a.existencia);
      p.getNombregenerico(a.nombregenerico);
      p.getCaducidad(a.caducidad);
      p.getFormafarmaceutica(a.formafarmaceutica);*/
     
     
      escribir.close();
   }catch(IOException e){
   
   System.out.println("Error al escribir");
   }
   }
   
   public void listado(Productos []p, int x)throws FileNotFoundException,IOException
   {
      try{
      File archivo = new File("archiyect.txt");
      FileWriter escribir = new FileWriter(archivo,true);//¿hacer esto por cada metodo?
     
      for(int z=0; z<x;z++)
      {
      JOptionPane.showMessageDialog(null,"La clave del producto es:"+p[z].getClave()+"\n"
      +"El nombre del producto es:"+p[z].getNombre()+"\n"
      +"El precio  del producto es:"+p[z].getPrecio()+"\n"
      +"La existencia del producto es:"+p[z].getExistencia()+"\n"
      );
      }//termina for
   }catch(IOException e){
   
   JOptionPane.showMessageDialog(null,"Error al escribir ");
   }
   }
   //CONSULTA POR CLAVE
   public void consultasc(Productos []p1,int x)
   {
    String claveb;
    String desc="NULL";
    int h=0,j=0;
    claveb = JOptionPane.showInputDialog("Cual es la clave del producto");
   
    String busca = claveb;
    String[]v = busca.split(" ");
   
    for(int i=0; i<x; i++){
       desc = p1[i].getClave();
       
       if(desc.equalsIgnoreCase(busca)){ //equalsIgnore
          h = i;
            } 
          }
      JOptionPane.showMessageDialog(null,"La clave del producto es:"+p1[h].getClave()+"\n"
      +"El nombre del producto es:"+p1[h].getNombre()+"\n"
      +"El precio  del producto es:"+p1[h].getPrecio()+"\n"
      +"La existencia del producto es:"+p1[h].getExistencia()+"\n"
      );
     //return x;
   }
   
   //CONSULTA POR NOMBRE
   public void consultasn(Productos []p1,int x)
   {
    String nombreb;
    int ll=0,j=0;
    String desc="NULL";
    nombreb = JOptionPane.showInputDialog("Cual es el nombre del producto");
   
    String busca = nombreb;
    String[]v = busca.split(" ");
   
    for(int i=0;i<x;i++){
       desc=p1[i].getNombre();
       
       if(desc.equalsIgnoreCase(busca)){
          ll=i;
            } 
          }
      JOptionPane.showMessageDialog(null,"La clave del producto es:"+p1[ll].getClave()+"\n"
      +"El nombre del producto es:"+p1[ll].getNombre()+"\n"
      +"El precio  del producto es:"+p1[ll].getPrecio()+"\n"
      +"La existencia del producto es:"+p1[ll].getExistencia()+"\n"
      );
     //return x;
   }
   
   
   public void bajas(Productos[] pb, int x)throws FileNotFoundException,IOException
   {
    int h = 0;
    String bajaclave;
    bajaclave = JOptionPane.showInputDialog("Cual es la clave del producto");
    String baja = bajaclave;
   
        for(int y=0;y<x;y++){
            String nomb = pb[y].getClave();
            if(nomb.equalsIgnoreCase(baja)){
                h = y;
                JOptionPane.showInputDialog(null,"El producto"+pb[h].getClave()+ "\n"+pb[h].getNombre()+"\n","Quiere darlo de baja?(si/no)");
               String r = bajaclave;
                if(r.equalsIgnoreCase("si"))
                    for(int a=h;a<x;a++)
                        pb[a]=pb[a+1];
                x--;
                p--;
                y=x;
                if(r.equalsIgnoreCase("no"))
                JOptionPane.showMessageDialog(null,"No se eliminara");
                }
               

         }

   
     
 
}
}

Código: [Seleccionar]
import java.io.*;
import javax.swing.JOptionPane;
public class Implementacion
{
   public static void main(String args[])throws FileNotFoundException, IOException
   {     
      Metodos obj = new Metodos();
      Productos[] p = new Productos[20];
     
      String opcions;
      int x=0;
      int opcion;
    do{
    opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Listado de productos\n 3.Consulta de productos\n 4.Bajas\n 5.SALIR\n");
    //opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Consulta productos\n 3.Baja porductos\n 4.Modificacion de un producto\n 5.Listado de productos\n 6. Salir\n ");
      opcion=Integer.parseInt (opcions);
    switch(opcion)
    {
    case 1:obj.altas();
       break;
    case 2:obj.listado(p, x);
       break;
    case 3:
       String opcionl;
       int opc;
                do{
                    opcionl=JOptionPane.showInputDialog ("Menu\n 1.Busqueda por clave\n 2.Busqueda por nombre\n");
                    opc=Integer.parseInt(opcionl);
                    switch(opc){
                        case 1:
                          obj.consultasc(p, x);

                            break;
                        case 2:
                          obj.consultasn(p,x);
                            break;
                        case 3:
                            break;
                    }
                }while(opc!=3);
                break;
       case 4: obj.bajas(p,x);
       break;
       case 5:
       break;
       
   
    }while(opcion!=5);}   
    }

Sólo me guarda las altas en los archivos, pero no realiza los demas métodos :/

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
Voy a echarle un vistazo a todo en cuanto tenga tiempo, que ya se me terminaron las vacaciones, he vuelto al trabajo y ya no tengo tanto tiempo para dedicarle a esto. :-\

Pero para empezar, veo un par de cosas que no me cuadran:

La clase Productos, has definido su constructor indicando que va a recibir 7 parámetros, uno por cada atributo.
Sin embargo, el código del constructor solo recoge los primeros 4 atributos, los otros 3 (nombregenerico, caducidad y forma farmecutica) los ignora:
Código: [Seleccionar]
public Productos(String clave, String nombre, int precio, int existencia, String nombregnerico, int caducidad, String formafarmaceutica)
   {
   this.clave = clave;
   this.nombre = nombre;
   this.precio = precio;
   this.existencia = existencia;
   }

Ya que para construir un Producto pedimos 7 parametros, habría que recogerlos.
O bien reducir los parametros necesarios para la construcción a solo 4, si valoramos que los otros 3 no son importantes y pueden ser establecidos a posteriori usando los setters.

Es importante tomar una decisión sobre esto, porque esta decisión influye a la hora de crear objetos de la clase Medicamentos.
Esta clase hereda de Productos, esto significa que el constructor de Medicamentos, ha de pedir, como mínimo, los mismos parámetros que pide el constructor de Productos, ya que Medicamentos en su constructor, ha de pasarle esos parametros a su "superclase" Productos mediante el método super().

Esto significa que ahora mismo tu constructor de Medicamentos es erróneo y no funciona. No lo has notado porque en la Implementacion no estas construyendo Medicamentos, solo estás construyendo Productos. No se si es así como tienes que hacerlo (en cuyo caso la clase Medicamentos no sirve para nada) o te estás equivocando y lo que tienes que dar de alta, baja, etc.. son Medicamentos y no Productos

En cualquier caso, repito que ahora mismo tu constructor de Medicamentos es incorrecto:
Código: [Seleccionar]
public Medicamentos()
   {
      nombregenerico = null;
      caducidad = 0;
      formafarmaceutica = null;
      concentracion = 0;
   }
Para que se compilable y ejecutable, ha de incluir la llamada al super() (a la clase padre de la que hereda) y pasarle los parametros que este requiere para ser construido.
Por lo tanto, el constructor de Medicamentos ha de pedir también estos parametros.

Código: [Seleccionar]
public Medicamentos(String clave, String nombre, int precio, int existencia, String nombregenerico, int caducidad, String formafarmaceutica)
   {
  super(clave, nombre, precio, existencia, nombregenerico, caducidad, formafarmaceutica);
      nombregenerico = null;
      caducidad = 0;
      formafarmaceutica = null;
      concentracion = 0;
   }

Este constructor sí es compilable y ejecutable. Java lo dará por bueno y el programa funcionará.
Sin embargo, no es correcto. Hay errores de diseño en las clases, hay atributos repetidos.
Lo atributos: nombregenerico, caducidad y forma farmecutica están declarados en ambas clases, que son precisamente los atributos que el constructor de Productos estaba ignorando.
Supongo que se debe a que esos atributos deberían ser declarados solo para Medicamentos.
Así que vamos a redefinir las dos clases haciendo una distribución más lógica de sus atributos.

La clase Productos debería quedar solo con estos 4 atributos (y sus correspondientes getters/setters), que es de suponer son los únicos atributos comunes a todos los Productos, ya sean:
Productos->Medicamentos,
..o Productos->Vacunas(esta es otra clase que podría ser también heredera),
.. o lo que sea...

Código: [Seleccionar]
public class Productos
{
   private String clave;
   private String nombre;
   private int precio;
   private int existencia;

   
   public Productos(String clave, String nombre, int precio, int existencia)
   {
   this.clave = clave;
   this.nombre = nombre;
   this.precio = precio;
   this.existencia = existencia;
   }
   
   public void setClave(String clave)
   {
      this.clave = clave;
   }
   public String getClave()
   {
      return clave;
   }
   public void setNombre(String nombre)
   {
      this.nombre = nombre;
   }
   public String getNombre()
   {
      return nombre;
   }
   public void setPrecio(int precio)
   {
      this.precio = precio;
   }
   public int getPrecio()
   {
      return precio;
   }
   public void setExistencia(int existencia)
   {
      this.existencia = existencia;
   }
   public int getExistencia()
   {
      return existencia;
   }
   
}

Y entonces la clase Medicamentos, aporta 4 atributos más:
nombregenerico, caducidad, formafarmaceutica y concentracion

Por lo tanto, su constructor puede pedir 8 parámetros, 4 para pasarlos a su superclase Productos y los otros 4 para sus propios atributos.
Pero no es obligatorio pedir 8, la única cifra obligatoria es pedir los 4 necesarios para los atributos de Productos

Fíjate que incluso, podemos crear dos constructores y luego en la Implementacion podemos usar el que nos de la gana.
Un constructor solo pedirá los 4 necesarios para cumplir con la herencia de Productos, el resto de atributos se tendrían que establecer mediante los setters
El otro constructor si pedirá los 8 atributos completos, de forma que el objeto Medicamento quedaría completamente construido de una sola vez.

Aquí tienes la clase Medicamentos con los dos constructores.
Fíjate que en ambos constructores, la instrucción super() siempre ha de recibir esos 4 parámetros básicos necesarios para construir un Producto
Esto siempre es obligatorio cuando una clase hereda de otra clase.

Código: [Seleccionar]
public final class Medicamentos extends Productos
{
private String nombregenerico; //acido
private int caducidad;
private String formafarmaceutica;//tabletas, pastillas, jarabe
private int concentracion; //500 mg

public Medicamentos(String clave, String nombre, int precio, int existencia)
{
super(clave, nombre, precio, existencia);
nombregenerico = null;
caducidad = 0;
formafarmaceutica = null;
concentracion = 0;
}

public Medicamentos(String clave, String nombre, int precio, int existencia, String nombregenerico, int caducidad, String formafarmaceutica, int concentracion)
{
super(clave, nombre, precio, existencia);
this.nombregenerico = nombregenerico;
this.caducidad = caducidad;
this.formafarmaceutica = formafarmaceutica;
this.concentracion = concentracion;
}

public String getNombregenerico() {
return nombregenerico;
}

public void setNombregenerico(String nombregenerico) {
this.nombregenerico = nombregenerico;
}

public int getCaducidad() {
return caducidad;
}

public void setCaducidad(int caducidad) {
this.caducidad = caducidad;
}

public String getFormafarmaceutica() {
return formafarmaceutica;
}

public void setFormafarmaceutica(String formafarmaceutica) {
this.formafarmaceutica = formafarmaceutica;
}

public int getConcentracion() {
return concentracion;
}

public void setConcentracion(int concentracion) {
this.concentracion = concentracion;
}

}

Vale, aquí ya tenemos las dos clases bien definidas y cumpliendo con las herencias.
Revisa el enunciado de tu ejercicio. Si indica que los atributos han de ir repartidos de otra forma entre estas clases, dilo y lo cambiamos. Lo que desde luego no puede decir es que un mismo atributo está definida en ambas clases. Eso es redundante e innecesario.

Y revisa también si en la Implementacion lo que debemos dar de alta, baja, etc.. son Productos o Medicamentos. Lo lógico sería que trabajásemos con Medicamentos.

El resto del ejercicio lo revisaré entre este Sábado y Domingo. Ahora mismo no puedo dedicarle más tiempo.
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

janegg

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 18
    • Ver Perfil
Hola! antes que nada muchas gracias por la ayudaa!
Sí, los métodos se deben realizar con los medicamentos, está muy bien así como lo planteaste.
Respecto a los métodos solo me han funcionan las altas :(

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
Hola de nuevo. Ya he revisado todo el programa.
Te comento los cambios que pienso (pienso yo, no tiene por qué ser la única o la mejor forma de hacer un programa) podríamos hacer para que funcionase bien y además quede todo más simplificado, fácil de entender y de mantener.

Tenemos dos clases más: la clase Metodos y la clase Implementacion

Implementacion es la que se encarga de lanzar el programa y mostrar al usuario un menu de opciones.
Y creo que debería limitarse precisamente a eso y a nada más. Recoger la opcion elegida por el usuario y pedirle a Metodos que actúe según esa opcion.

Metodos será quien se encargue de leer y escribir datos en el archivo de texto, quien tenga un array en memoria con los datos de los Medicamentos con los que estamos trabajando, quien active los procesos de dar de alta, de baja, consulta, listado...
Va a ser quien realice todo el "trabajo duro", toda la labor interna del programa.

Implementacion en cambio no hará gran cosa, solo mostrar un menú.
Código: [Seleccionar]
import java.io.*;
import javax.swing.JOptionPane;
public class Implementacion
{

public static void main(String args[])throws FileNotFoundException, IOException
{     
//Inicializamos el objeto que contiene y gestiona todos los datos y funciones del programa
Metodos metodos = new Metodos();

String opcions;
int opcion;
do{
opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Listado de productos\n 3.Consulta de productos\n 4.Bajas\n 5.SALIR\n");
//opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Consulta productos\n 3.Baja porductos\n 4.Modificacion de un producto\n 5.Listado de productos\n 6. Salir\n ");
opcion=Integer.parseInt (opcions);
switch(opcion)
{
case 1:
metodos.altas();
break;
case 2:
metodos.listado();
break;
case 3:
String opcionl;
int opc;
do{
opcionl=JOptionPane.showInputDialog ("Menu\n 1.Busqueda por clave\n 2.Busqueda por nombre\n 3.SALIR");
opc=Integer.parseInt(opcionl);
switch(opc){
case 1:
metodos.consultasc();
break;
case 2:
metodos.consultasn();
break;
}
}while(opc!=3);
break;
case 4:
metodos.bajas();
break;
case 5:
JOptionPane.showMessageDialog(null, "FIN del programa");
break;
default:
JOptionPane.showMessageDialog(null, "Opcion invalida");

}while(opcion!=5);
}   
}

En realidad apenas he modificado la clase que tu ya tenias escrita. Tan solo eliminar un array que había declarado, una variable y poco más.
Fíjate que la primera linea es inicializar a Metodos que ya hemos dicho que será quien haga el trabajo de verdad.
Ahora además las llamadas a los metodos .listado(), consulta(), baja(),... se han simplificado. Ya no hay que pasarles parámetros entre parentesis, ya que todos los datos de trabajo ya los posee la clase Metodos y los gestiona ella. No necesita informacion externa.

Ahora vamos con la clase Metodos, que obviamente es la más interesante.
Antes es importante aclarar como vamos a trabajar con los datos.
El programa gestiona Medicamentos y estos se guardan en un archivo de texto para poder recuperarlos cada vez que se reinicie el programa.

A este archivo solo debemos acceder para recuperar los datos al iniciar el programa y guardar cambios como altas o bajas, no para hacer consultas o listados.
Para estos procesos tenemos que tener un array en memoria con todos los objetos Medicamentos, lo que nos permite trabajar con más rapidez y seguridad.

Para este tipo de programas, un array primitivo se nos queda muy limitado. Especialmente porque hay que indicarles un tamaño fijo.
Tu declaraste uno de tamaño 20, que bueno, para un ejercicio de práctica puede valer. Pero obviamente es una limitación importante.

Para evitar estas limitaciones podemos usar una estructura de datos más dinámica y avanzada. En Java hay varias para elegir, todas similares pero con ciertos matices.
Pero para no complicarnos la vida, es muy habitual usar el tipo ArrayList.
En esencia es muy similar a un array primitivo, pero tiene la ventaja de que no hay que indicar un tamaño fijo. Se le pueden añadir o eliminar elementos y su tamaño se irá adaptando a estos cambios.
Así que está sera la estructura que usaremos para tener los Medicamentos en memoria.

Para que los distintos metodos que va a tener la clase Metodos puedan acceder sin problemas tanto al ArrayList como al archivo de texto y hacer su trabajo, estos dos elementos los vamos a declarar como atributos de esta clase.
Tendremos un atributo File con la ruta del archivo ya predefinida y un ArrayList inicializado para poder albergar objetos Medicamentos

Además Metodos va a tener un constructor, pero en este caso va a hacer una tarea algo distinta a la habitual de recibir valores para pasar a los atributos.
Este constructor lo que va a hacer es comprobar si hay ya creado un archivo de texto.
Y si lo hay, recogerá los datos que contenga, construirá objetos Medicamentos y los añadirá al ArrayList.
De este modo, nuestro programa lo primero que hará al iniciarse será recuperar los datos guardados (si los hubiere) y los tendremos listos para trabajar con ellos.

Algo de lo que hay que hablar ahora, es de como vamos a guardar los datos en el archivo de texto.
Lo ideal es que cada linea del archivo contenga los datos (los 8 atributos) de un medicamento. Así sabremos que cada linea corresponde a un medicamento.
Los datos deberían ir separados por algún simbolo para que luego, cuando el programa lea la linea y quiera construir un objeto Medicamento con esos datos, sepa como separar esos datos y a que atributo pertenece a cada uno.
Yo he elegido separarlos por un doble guion -->  "--" pero vamos, podría ser cualquier otro simbolo.
De este modo, tendríamos un archivo de texto como este:

Citar
001--Frenadol--15--300--null--0--null--0
002--Focusin--35--250--null--0--null--0
003--Betadine--10--475--null--0--null--0

Cada linea es un medicamento, y cada atributo está diferenciado de los demás por el doble guion.

Para crear estas lineas, lo más comodo es que a la clase Medicamentos le añadamos un nuevo método.
Es el método toString(), que nos permite sobreescribirlo para que decidamos como queremos construir un String que sirva para mostrar los datos de dicho objeto.
Es aquí donde podemos meter los atributos separados por el doble guion y tener ya construida la linea que escribiremos en el archivo de texto.

Así que ha Medicamentos, le vamos a añadir este método:
Código: [Seleccionar]
@Override
public String toString()
{
return super.getClave() + "--" + super.getNombre() + "--" + super.getPrecio() + "--" + super.getExistencia()
+ "--" + nombregenerico + "--" + caducidad + "--" + formafarmaceutica + "--" + concentracion;
}

Con esto ya podremos escribir de forma sencilla lineas de texto que contengan toda la info de cada Medicamento.

Vamos a ver ya la clase Metodos, la pongo 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
Metodos
Código: [Seleccionar]
import javax.swing.JOptionPane;
import java.io.*;
import java.util.ArrayList;

public class Metodos {

private File archivo = new File("c:\\prueba\\archiyect.txt");
private ArrayList<Medicamentos> medicamentos = new ArrayList<>();

public Metodos()
{
/*
* El constructor de Metodos lo que hará es comprobar si ya existe un
* archivo con datos de Medicamentos ya creado.
* Si existe, recuperará estos datos, creará objetos Medicamentos y los
* pasará al ArrayList desde donde podremos trabajar con ellos.
* Si no existe, no hará nada, tendremos un ArrayList vacio listo para
* que podamos hacer las primeras altas.
*/
if (archivo.exists())
{
try {
BufferedReader leer = new BufferedReader(new FileReader(archivo));
String linea = leer.readLine();
while(linea != null)
{
/*
* Separamos los atributos del Medicamento de la linea que hemos leido
* En la linea los atributos estan separados por un doble guion "--"
* La linea contendrá los 8 atributos correspondientes a un Medicamento.
* Sin embargo, los 4 últimos es posible que no tengan datos validos, si no que
* puede que contengan valores null y 0, ya que los únicos atributos que son
* de obligatoria cumplimentación son los primeros 4.
*/

String[] atributos = linea.split("--");
//Los 4 atributos obligatorios
String clave = atributos[0];
String nombre = atributos[1];
int precio = Integer.parseInt(atributos[2]);
int existencia = Integer.parseInt(atributos[3]);

/*
* Ahora recogemos los 4 atributos opcionales.
* Los de tipo String, si no fueron cumplimentados,
* tendrían valor null  y en el archivo de texto se
* habrá escrito la palabra "null". Sin embargo,
* al leer del archivo estamos recibiendo un String
* con el texto "null". No podemos pasar este texto
* directamente al atributo, sino que en este caso
* debemos pasar el valor null, que no es lo mismo
* que un string con el texto "null". Son cosas distintas.
*/
String nombreGenerico;
if (atributos[4].equals("null"))//Este atributo tenía valor null cuando se guardo en el archivo
nombreGenerico = null;
else
nombreGenerico = atributos[4];

int caducidad = Integer.parseInt(atributos[5]);

String formaFarmaceutica;
if (atributos[6].equals("null"))
formaFarmaceutica = null;
else
formaFarmaceutica = atributos[6];

int concentracion = Integer.parseInt(atributos[7]);

/*
* Ya tenemos los 8 atributos.
* Podemos añadir al ArrayList un nuevo Medicamento.
*/

medicamentos.add(new Medicamentos(clave, nombre, precio, existencia, nombreGenerico,
caducidad, formaFarmaceutica, concentracion));
//Medicamento añadido, leemos una nueva linea y si contiene datos, se repetirá este proceso
linea = leer.readLine();
}
leer.close();
//Lectura concluida.
//Podemos informar por pantalla cuantos Medicamentos hemos recuperado del archivo
JOptionPane.showMessageDialog(null, "Cantidad de Medicamentos recuperados: " + medicamentos.size(),
"Datos Leidos", JOptionPane.INFORMATION_MESSAGE);
} catch (Exception ex)
{
JOptionPane.showMessageDialog(null, "No se pudo leer datos del archivo: " + archivo.getAbsolutePath(),
"Error de Lectura", JOptionPane.WARNING_MESSAGE);
}
}
}

public void altas() throws FileNotFoundException,IOException
{
/*
* Los Medicamentos tienen 8 atributos, pero para su creacion solo
* son obligatorios propocionar 4. En este ejemplo solo pediremos
* los 4 atributos obligatorios.
*/

String clave = JOptionPane.showInputDialog("Dame la clave del producto");
String nombre = JOptionPane.showInputDialog("Escribe el nombre del producto");
int precio = Integer.parseInt(JOptionPane.showInputDialog("Escribe el precio del producto"));
int existencia = Integer.parseInt(JOptionPane.showInputDialog("Cuántos productos hay en existencia"));

/*
* Tenemos los 4 atributos.
* Crearemos un Medicamento y lo añadiremos al ArrayList.
* Luego, lo añadiremos al archivo de texto en disco.
*/
Medicamentos nuevoMed = new Medicamentos(clave, nombre, precio, existencia);
medicamentos.add(nuevoMed);

try{
BufferedWriter escribir = new BufferedWriter(new FileWriter(archivo, true));
escribir.write(nuevoMed.toString());
escribir.newLine();
escribir.close();
}catch(IOException e){
JOptionPane.showMessageDialog(null, "No se pudo escribir datos en archivo: " + archivo.getAbsolutePath(),
"Error de Escritura", JOptionPane.WARNING_MESSAGE);
}
}

/**
* Este metodo contruye un String con todos los datos de un
* Medicamento para ser mostrado en pantalla.
* Es útil porque puede ser utilizado para las funciones
* de listado, búsqueda por clave, busqueda por nombre..
* @param m Objeto Medicamentos que queremos mostrar.
* @return Cadena String con todos los datos
*/
private String mensajeMedicamento(Medicamentos m)
{
return "Clave: " + m.getClave()
+ "\nNombre: " + m.getNombre()
+ "\nPrecio: " + m.getPrecio()
+ "\nExistencias: " + m.getExistencia()
+ "\nNombre Generico: " + m.getNombregenerico()
+ "\nCaducidad: " + m.getCaducidad()
+ "\nForma Farmaceutica: " + m.getFormafarmaceutica()
+ "\nConcentracion: " + m.getConcentracion();
}

public void listado()
{
/*
* Recorremos el ArrayList y por cada Medicamento existente
* construimos un mensaje con los datos y lo mostramos en un
* Dialogo de Confirmacion.
* El usuario tiene la oportunidad de finalizar el listado pulsando
* el boton NO de este dialogo.
* Antes de nada, por supuesto, hemos de comprobar si existen medicamentos
* ya registrados
*/
if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
for (int i = 0; i < medicamentos.size(); i++)
{
/*
* Para mostrar el medicamento usamos el String que nos devuelve el metodo
* mensajeMedicamento() y además le añadimos otra linea indicando al usuario
* que puede detener el listado pulsando el boton NO de la ventana de dialogo.
* Esta ventana, en su título superior, además mostrará el número de posicion
* que ocupa este Medicamento en el ArrayList y el total que hay.
* Un mensaje tipo ---> Medicamento nº 4/30
* Así el usuario tendrá una idea de cuantos Medicamentos quedan por listar.
*/
String mensaje = mensajeMedicamento(medicamentos.get(i)) + "\n\n¿Desea seguir visualizando el listado?";

int seguir = JOptionPane.showConfirmDialog(null, mensaje, "Medicamento nº " + (i+1) + "/" + medicamentos.size(), JOptionPane.YES_NO_OPTION);

if (seguir == JOptionPane.NO_OPTION)//Usuario NO quiere seguir con el listado, "rompemos" el bucle
break;
}
}
}
//CONSULTA POR CLAVE
public void consultasc()
{
if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
String clave = JOptionPane.showInputDialog("Introduzca clave a buscar:");

/*
* Recorremos el ArrayList mediante un bucle FOR EACH para buscar el Medicamento con
* la clave que nos han indicado.
* Si lo encontramos, mostramos sus datos y detenemos el bucle de búsqueda.
* Si no lo encontramos, habría que informar al usuario de que no existe dicha clave.
* Para controlar si hemos encontrado o no el Medicamento, podemos usar una variable
* booleana. Esta variable comenzará con valor false.
* Si lo encontramos, la pondremos a true.
* Al terminar el bucle de busqueda, si esta variable conserva el valor false inicial,
* sabremos que el Medicamento no fue encontrado e informaremos al usuario.
*/
boolean encontrado = false;
for (Medicamentos m:medicamentos)
{
if (m.getClave().equalsIgnoreCase(clave))
{
encontrado = true;//¡¡Lo hemos encontrado!!
JOptionPane.showMessageDialog(null, mensajeMedicamento(m), "Mostrando medicamento", JOptionPane.INFORMATION_MESSAGE);
}
}
//Bucle de busqueda terminado, hemos de comprobar si fue encontrado el medicamento o no
if (!encontrado)
JOptionPane.showMessageDialog(null, "No se encontro medicamento con clave: " + clave, "Mostrando medicamento", JOptionPane.INFORMATION_MESSAGE);
}

}

//CONSULTA POR NOMBRE
public void consultasn()
{
//Igual que consultas por clave, pero ahora por nombre
}


public void bajas()throws FileNotFoundException,IOException
{
/*
* El metodo para hacer bajas es muy parecido al metodo de consulta por clave.
* Solo que esta vez al encontrar el medicamento, este ha de ser eliminado del
* ArrayList y también del fichero de texto donde guardamos los datos.
* Borrar del ArrayList se hace con una sencilla instruccion.
* Borrar la linea de datos del archivo de texto, es un poco más laborioso.
* Para facilitar la tarea, lo ideal es eliminar el archivo por completo
* y volver a crearlo de nuevo con todos los Medicamentos contenidos en el
* ArrayList, donde ya no estará el Medicamento que hemos dado de baja.
*/
if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
String clave = JOptionPane.showInputDialog("Introduzca clave de Medicamento a eliminar:");
boolean encontrado = false;//Para controlar si lo hemos encontrado
boolean borrado = false;//Para controla si el usuario ha decidido eliminarlo
for (int i = 0; i < medicamentos.size(); i++)
{
if (medicamentos.get(i).getClave().equalsIgnoreCase(clave))
{
encontrado = true;
String mensaje = mensajeMedicamento(medicamentos.get(i)) + "\n\n¿Desea dar de baja?";
int confirmar = JOptionPane.showConfirmDialog(null, mensaje, "Confirmar Baja", JOptionPane.YES_NO_OPTION);
if (confirmar == JOptionPane.YES_OPTION)//SI quiere dar de baja
{
//Eliminamos del ArrayList
medicamentos.remove(i);
borrado = true;
}
}
}
/*
* Bucle de busqueda terminado ahora comprobamos si el Medicamento fue encontrado o no.
* Si no fue encontrado, informamos al usuario con un mensaje
* Si fue encontrado y eliminado guardaremos los datos actualizados en el archivo de texto.
* Para crear este archivo habrá que recorrer de nuevo el ArrayList y añadir una linea de texto
* por cada Medicamento que contenga.
*/
if (encontrado && borrado)
{
try {
//Intentamos borrar archivo actual
if (archivo.delete())
{
//Archivo borrado, creamos uno nuevo actualizado
BufferedWriter escribir = new BufferedWriter(new FileWriter(archivo, true));
for (Medicamentos m:medicamentos)
{
escribir.write(m.toString());
escribir.newLine();
}
escribir.close();
JOptionPane.showMessageDialog(null, "Medicamento eliminado.\nLos cambios se han guardado", "Baja de Medicamento",
JOptionPane.INFORMATION_MESSAGE);
}
else//Por algun motivo, no se pudo borrar archivo
{
JOptionPane.showMessageDialog(null, "Error de acceso a archivo.\nLos cambios no han sido guardados", "Baja de Medicamento",
JOptionPane.WARNING_MESSAGE);
}
} catch(Exception ex) {
JOptionPane.showMessageDialog(null, "Error de acceso a archivo\nTipo de error: " + ex.getLocalizedMessage());
}
}
else if(!encontrado)//No fue encontrado
{
JOptionPane.showMessageDialog(null, "NO se encontro Medicamento con la clave: " + clave, "Baja de Medicamentos",
JOptionPane.INFORMATION_MESSAGE);
}

}
}
}

Es la clase más grande y tiene muchas lineas de código, aunque la verdad muchas son lineas de comentarios donde explico lo que se va haciendo a cada paso para que se entienda mejor.

Comienza con 2 atributos: el ArrayList y el objeto File identificando al archivo con el que vamos a trabajar.
La ventaja de declararlos como atributos de clase es que así están visibles para todos los metodos y no hay problemas de "alcance"(scope).

Luego el constructor, que se encarga de ver si ya existe un archivo con datos y si lo hay, leerá cada linea de este para construir Medicamentos y pasarlos al ArrayList.
Para leer lineas estamos usando la clase BufferedReader. Es parecida a la FileReader, de hecho, para construir un BufferedReader tenemos que pasarle un FileReader.
La ventaja es que BufferedReader lee lineas de texto completas, FileReader solo lee caracter a caracter.
En los comentarios hago algunas explicaciones más detalladas, que no haré aquí para no extenderme demasiado. Si tienes dudas de por qué hago tal cosa o la otra, pregúntalas y ya profundizamos más.

Luego vienen los metodos:
  • altas()
  • listado()
  • consultasc()
  • consultasn()
  • bajas()

Todos tienen comentarios explicando paso a paso. Así que ahora explico solo un poco por encima para no extenderme. De nuevo, si tienes dudas concretas, pregunta y las tratamos luego:

-altas()
Es muy facil. Pedimos los 4 atributos mínimos obligatorios (pedir 8 son muchos y hace que testear el ejercicio sea mas tedioso).
Construimos un Medicamento, lo añadimos al ArrayList y añadimos una nueva linea de texto al archivo.
Para escribir, usamos la clase BufferedWriter ya que, al igual que su hermana BufferedReader, nos permite trabajar con lineas completas y no solo caracter a caracter.

-listado()
Muy facil también. Recorremos el ArrayList y por cada Medicamento encontrado mostramos sus atributos en una ventana de diálogo.
Cada vez que se muestra la ventana, el usuario puede escoger entre seguir adelante con el listado o detenerlo. De este modo no se le obliga a ver todo el listado completo (imagina que tenemos 50 Medicamentos, o 100...)

-consultasc()
Pedimos la clave y recorremos el ArrayList preguntando si algún Medicamento coincide con la clave que nos han dado.
Si lo encontramos, lo mostramos en pantalla.
Si no lo encontamos, informamos de que no existe medicamento con esa clave

-consultasn()
Este no lo he escrito, te lo dejo para que lo hagas tú.
En realidad es lo mismo que el anterior, solo que esta vez buscaremos por nombre.

-bajas()
Buscamos Medicamento por clave.
Si lo encontramos pedimos confirmacion para borrarlo.
Si el usuario confirma la baja, lo borramos del ArrayList y además tenemos que actualizar el archivo de texto.
Borrar lineas de un archivo de texto creo que puede ser un poco lioso, así que lo fácil  y rápido es eliminar por completo el archivo existente y volver a crearlo de nuevo con los datos del ArrayList, donde ya no se encuentra el Medicamento que hemos dado de baja.

Hay otro método, declarado como private (ya que es para uso interno de esta clase) llamado mensajeMedicamento()
Este es un método de apoyo.
Fíjate que en los metodos listado(), consultac()  y consultan() vamos a tener que mostrar una ventana con todos los datos, los 8 atributos, del Medicamento. Esto implica escribir varias linea para construir un String bastante grande.
Pues en lugar de repetir este proceso en varios sitios, lo que hacemos es crear un metodo que se encargue de esta tarea. Recibe un objeto Medicamento y devuelve un String, con texto,datos y saltos de linea..., listo para mostrar como mensaje al usuario.

Y bueno, el programa ya está funcionando perfectamente.

Solo quedaría escribir el metodo de consultas por nombre.
Y supongo que además habría que crear un nuevo metodo que permitiese modificar un Medicamento ya creado.
Este método sería posiblemente el más laborioso de realizar, aunque no es tampoco demasiado difícil y de hecho, sería muy similar al metodo de bajas().
La única diferencia es que en lugar de eliminar un objeto, ofrecemos la posibilidad de modificarlo

A ver si consigues hacerlo tú.

Y de nuevo, no dudes en preguntar lo que sea. No hay nada especialmente dificil, pero las cosas cuando se ven por primera vez, lo parecen.
Así que no te quedes con dudas.
Lo importante no es hacer el ejercicio, sino aprender haciéndolo.
« Última modificación: 10 de Junio 2018, 14:39 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

janegg

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 18
    • Ver Perfil
Muchas gracias en serio!! Sí haré las consultas por nombre, en ese momento sólo puedo ver el código pero más tarde lo intetaré.
También tengo que hacer el método de eliminación y modificación, pero si tienes razón es parecido a las consultas. Trataré de implementarlos.
Muchas gracias, sin tengo dudas respecto a los siguientes métodos te preguntaré  :D
Buen día!

janegg

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 18
    • Ver Perfil
Muchas gracias en serio!! Sí haré las consultas por nombre, en ese momento sólo puedo ver el código pero más tarde lo intetaré.
También tengo que hacer el método de modificación, pero si tienes razón es parecido a las bajas. Trataré de implementarlos.
Muchas gracias, sin tengo dudas respecto a los siguientes métodos te preguntaré  :D
Buen día!

janegg

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 18
    • Ver Perfil
Holaa! Me ha surgido una gran duda, ya implemente el método de modificación, lo habia estado revisando y estaba bien. Pero quería mover ese método a otra clase, pero al momento de ejecutarse no modifica,  tendría que agregarle algo a todos los metodos si los quisera mover a otra clase?
Gracias.

Esta es la clase Métodos, a esta recientemente le habia agregado la modificacion
Código: [Seleccionar]
import javax.swing.JOptionPane;
import java.io.*;
import java.util.ArrayList;

public class Metodos {

private File archivo = new File("archiyect.txt");
private ArrayList<Medicamentos> medicamentos = new ArrayList<>();

public Metodos()
{
/*
* El constructor de Metodos lo que hará es comprobar si ya existe un
* archivo con datos de Medicamentos ya creado.
* Si existe, recuperará estos datos, creará objetos Medicamentos y los
* pasará al ArrayList desde donde podremos trabajar con ellos.
* Si no existe, no hará nada, tendremos un ArrayList vacio listo para
* que podamos hacer las primeras altas.
*/
if (archivo.exists())
{
try {
BufferedReader leer = new BufferedReader(new FileReader(archivo));
String linea = leer.readLine();
while(linea != null)
{
/*
* Separamos los atributos del Medicamento de la linea que hemos leido
* En la linea los atributos estan separados por un doble guion "--"
* La linea contendrá los 8 atributos correspondientes a un Medicamento.
* Sin embargo, los 4 últimos es posible que no tengan datos validos, si no que
* puede que contengan valores null y 0, ya que los únicos atributos que son
* de obligatoria cumplimentación son los primeros 4.
*/

String[] atributos = linea.split("--");
//Los 4 atributos obligatorios
String clave = atributos[0];
String nombre = atributos[1];
int precio = Integer.parseInt(atributos[2]);
int existencia = Integer.parseInt(atributos[3]);

/*
* Ahora recogemos los 4 atributos opcionales.
* Los de tipo String, si no fueron cumplimentados,
* tendrían valor null  y en el archivo de texto se
* habrá escrito la palabra "null". Sin embargo,
* al leer del archivo estamos recibiendo un String
* con el texto "null". No podemos pasar este texto
* directamente al atributo, sino que en este caso
* debemos pasar el valor null, que no es lo mismo
* que un string con el texto "null". Son cosas distintas.
*/
String nombreGenerico;
if (atributos[4].equals("null"))//Este atributo tenía valor null cuando se guardo en el archivo
nombreGenerico = null;
else
nombreGenerico = atributos[4];

int caducidad = Integer.parseInt(atributos[5]);

String formaFarmaceutica;
if (atributos[6].equals("null"))
formaFarmaceutica = null;
else
formaFarmaceutica = atributos[6];

int concentracion = Integer.parseInt(atributos[7]);

/*
* Ya tenemos los 8 atributos.
* Podemos añadir al ArrayList un nuevo Medicamento.
*/

medicamentos.add(new Medicamentos(clave, nombre, precio, existencia, nombreGenerico,
caducidad, formaFarmaceutica, concentracion));
//Medicamento añadido, leemos una nueva linea y si contiene datos, se repetirá este proceso
linea = leer.readLine();
}
leer.close();
//Lectura concluida.
//Podemos informar por pantalla cuantos Medicamentos hemos recuperado del archivo
JOptionPane.showMessageDialog(null, "Cantidad de Medicamentos recuperados: " + medicamentos.size(),
"Datos Leidos", JOptionPane.INFORMATION_MESSAGE);
} catch (Exception ex)
{
JOptionPane.showMessageDialog(null, "No se pudo leer datos del archivo: " + archivo.getAbsolutePath(),
"Error de Lectura", JOptionPane.WARNING_MESSAGE);
}
}
}

public void altas() throws FileNotFoundException,IOException
{
/*
* Los Medicamentos tienen 8 atributos, pero para su creacion solo
* son obligatorios propocionar 4. En este ejemplo solo pediremos
* los 4 atributos obligatorios.
*/
String clave = JOptionPane.showInputDialog("Dame la clave del producto");
String nombre = JOptionPane.showInputDialog("Escribe el nombre del producto");
int precio = Integer.parseInt(JOptionPane.showInputDialog("Escribe el precio del producto"));
int existencia = Integer.parseInt(JOptionPane.showInputDialog("Cuántos productos hay en existencia"));
/*
* Tenemos los 4 atributos.
* Crearemos un Medicamento y lo añadiremos al ArrayList.
* Luego, lo añadiremos al archivo de texto en disco.
*/
Medicamentos nuevoMed = new Medicamentos(clave, nombre, precio, existencia);
medicamentos.add(nuevoMed);

try{
BufferedWriter escribir = new BufferedWriter(new FileWriter(archivo, true));
escribir.write(nuevoMed.toString());
escribir.newLine();
escribir.close();
}catch(IOException e){
JOptionPane.showMessageDialog(null, "No se pudo escribir datos en archivo: " + archivo.getAbsolutePath(),
"Error de Escritura", JOptionPane.WARNING_MESSAGE);
}
}

/**
* Este metodo contruye un String con todos los datos de un
* Medicamento para ser mostrado en pantalla.
* Es útil porque puede ser utilizado para las funciones
* de listado, búsqueda por clave, busqueda por nombre..
* @param m Objeto Medicamentos que queremos mostrar.
* @return Cadena String con todos los datos
*/
private String mensajeMedicamento(Medicamentos m)
{
return "Clave: " + m.getClave()
+ "\nNombre: " + m.getNombre()
+ "\nPrecio: " + m.getPrecio()
+ "\nExistencias: " + m.getExistencia()
+ "\nNombre Generico: " + m.getNombregenerico()
+ "\nCaducidad: " + m.getCaducidad()
+ "\nForma Farmaceutica: " + m.getFormafarmaceutica()
+ "\nConcentracion: " + m.getConcentracion();
}

public void listado()
{
/*
* Recorremos el ArrayList y por cada Medicamento existente
* construimos un mensaje con los datos y lo mostramos en un
* Dialogo de Confirmacion.
* El usuario tiene la oportunidad de finalizar el listado pulsando
* el boton NO de este dialogo.
* Antes de nada, por supuesto, hemos de comprobar si existen medicamentos
* ya registrados
*/
if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
for (int i = 0; i < medicamentos.size(); i++)
{
/*
* Para mostrar el medicamento usamos el String que nos devuelve el metodo
* mensajeMedicamento() y además le añadimos otra linea indicando al usuario
* que puede detener el listado pulsando el boton NO de la ventana de dialogo.
* Esta ventana, en su título superior, además mostrará el número de posicion
* que ocupa este Medicamento en el ArrayList y el total que hay.
* Un mensaje tipo ---> Medicamento nº 4/30
* Así el usuario tendrá una idea de cuantos Medicamentos quedan por listar.
*/
String mensaje = mensajeMedicamento(medicamentos.get(i)) + "\n\n¿Desea seguir visualizando el listado?";

int seguir = JOptionPane.showConfirmDialog(null, mensaje, "Medicamento nº " + (i+1) + "/" + medicamentos.size(), JOptionPane.YES_NO_OPTION);

if (seguir == JOptionPane.NO_OPTION)//Usuario NO quiere seguir con el listado, "rompemos" el bucle
break;
}
}
}
//CONSULTA POR CLAVE
public void consultasc()
{
if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
String clave = JOptionPane.showInputDialog("Introduzca clave del medicamento a buscar:");

/*
* Recorremos el ArrayList mediante un bucle FOR EACH para buscar el Medicamento con
* la clave que nos han indicado.
* Si lo encontramos, mostramos sus datos y detenemos el bucle de búsqueda.
* Si no lo encontramos, habría que informar al usuario de que no existe dicha clave.
* Para controlar si hemos encontrado o no el Medicamento, podemos usar una variable
* booleana. Esta variable comenzará con valor false.
* Si lo encontramos, la pondremos a true.
* Al terminar el bucle de busqueda, si esta variable conserva el valor false inicial,
* sabremos que el Medicamento no fue encontrado e informaremos al usuario.
*/
boolean encontrado = false;
for (Medicamentos m:medicamentos)
{
if (m.getClave().equalsIgnoreCase(clave))
{
encontrado = true;//¡¡Lo hemos encontrado!!
JOptionPane.showMessageDialog(null, mensajeMedicamento(m), "Mostrando medicamento", JOptionPane.INFORMATION_MESSAGE);
}
}
//Bucle de busqueda terminado, hemos de comprobar si fue encontrado el medicamento o no
if (!encontrado)
JOptionPane.showMessageDialog(null, "No se encontro medicamento con clave: " + clave, "Mostrando medicamento", JOptionPane.INFORMATION_MESSAGE);
}

}

//CONSULTA POR NOMBRE
public void consultasn()
{
//consultas por nombre
      if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
String nombre = JOptionPane.showInputDialog("Introduzca nombre del medicamento a buscar:");

/*
* Recorremos el ArrayList mediante un bucle FOR EACH para buscar el Medicamento con
* el nombre que nos han indicado.
* Si lo encontramos, mostramos sus datos y detenemos el bucle de búsqueda.
* Si no lo encontramos, habría que informar al usuario de que no existe dicho nombre.
* Para controlar si hemos encontrado o no el Medicamento, podemos usar una variable
* booleana. Esta variable comenzará con valor false.
* Si lo encontramos, la pondremos a true.
* Al terminar el bucle de busqueda, si esta variable conserva el valor false inicial,
* sabremos que el Medicamento no fue encontrado e informaremos al usuario.
*/
boolean encontrado = false;
for (Medicamentos m:medicamentos)
{
if (m.getNombre().equalsIgnoreCase(nombre))
{
encontrado = true;//¡¡Lo hemos encontrado!!
JOptionPane.showMessageDialog(null, mensajeMedicamento(m), "Mostrando medicamento", JOptionPane.INFORMATION_MESSAGE);
}
}
//Bucle de busqueda terminado, hemos de comprobar si fue encontrado el medicamento o no
if (!encontrado)
JOptionPane.showMessageDialog(null, "No se encontro medicamento con ese nombre: " + nombre, "Mostrando medicamento", JOptionPane.INFORMATION_MESSAGE);
}
     
}


public void bajas()throws FileNotFoundException,IOException
{
/*
* El metodo para hacer bajas es muy parecido al metodo de consulta por clave.
* Solo que esta vez al encontrar el medicamento, este ha de ser eliminado del
* ArrayList y también del fichero de texto donde guardamos los datos.
* Borrar del ArrayList se hace con una sencilla instruccion.
* Borrar la linea de datos del archivo de texto, es un poco más laborioso.
* Para facilitar la tarea, lo ideal es eliminar el archivo por completo
* y volver a crearlo de nuevo con todos los Medicamentos contenidos en el
* ArrayList, donde ya no estará el Medicamento que hemos dado de baja.
*/
if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
String clave = JOptionPane.showInputDialog("Introduzca clave de Medicamento a eliminar:");
boolean encontrado = false;//Para controlar si lo hemos encontrado
boolean borrado = false;//Para controla si el usuario ha decidido eliminarlo
for (int i = 0; i < medicamentos.size(); i++)
{
if (medicamentos.get(i).getClave().equalsIgnoreCase(clave))
{
encontrado = true;
String mensaje = mensajeMedicamento(medicamentos.get(i)) + "\n\n¿Desea dar de baja?";
int confirmar = JOptionPane.showConfirmDialog(null, mensaje, "Confirmar Baja", JOptionPane.YES_NO_OPTION);
if (confirmar == JOptionPane.YES_OPTION)//SI quiere dar de baja
{
//Eliminamos del ArrayList
medicamentos.remove(i);
borrado = true;
}
}
}
/*
* Bucle de busqueda terminado ahora comprobamos si el Medicamento fue encontrado o no.
* Si no fue encontrado, informamos al usuario con un mensaje
* Si fue encontrado y eliminado guardaremos los datos actualizados en el archivo de texto.
* Para crear este archivo habrá que recorrer de nuevo el ArrayList y añadir una linea de texto
* por cada Medicamento que contenga.
*/
if (encontrado && borrado)
{
try {
//Intentamos borrar archivo actual
if (archivo.delete())
{
//Archivo borrado, creamos uno nuevo actualizado
BufferedWriter escribir = new BufferedWriter(new FileWriter(archivo, true));
for (Medicamentos m:medicamentos)
{
escribir.write(m.toString());
escribir.newLine();
}
escribir.close();
JOptionPane.showMessageDialog(null, "Medicamento eliminado.\nLos cambios se han guardado", "Baja de Medicamento",
JOptionPane.INFORMATION_MESSAGE);
}
else//Por algun motivo, no se pudo borrar archivo
{
JOptionPane.showMessageDialog(null, "Error de acceso a archivo.\nLos cambios no han sido guardados", "Baja de Medicamento",
JOptionPane.WARNING_MESSAGE);
}
} catch(Exception ex) {
JOptionPane.showMessageDialog(null, "Error de acceso a archivo\nTipo de error: " + ex.getLocalizedMessage());
}
}
else if(!encontrado)//No fue encontrado
{
JOptionPane.showMessageDialog(null, "NO se encontro Medicamento con la clave: " + clave, "Baja de Medicamentos",
JOptionPane.INFORMATION_MESSAGE);
}

}
}
   
  /* public void modificacion()throws FileNotFoundException,IOException
   {
   if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
String clave = JOptionPane.showInputDialog("Introduzca la clave del Medicamento para modificar:");
boolean encontrado = false;//Para controlar si lo hemos encontrado
boolean borrado = false;//Para controla si el usuario ha decidido eliminarlo
for (int i = 0; i < medicamentos.size(); i++)
{
if (medicamentos.get(i).getClave().equalsIgnoreCase(clave))
{
encontrado = true;
String mensaje = mensajeMedicamento(medicamentos.get(i)) + "\n\n¿Desea modificar este medicamento?";
int confirmar = JOptionPane.showConfirmDialog(null, mensaje, "Confirmar Baja", JOptionPane.YES_NO_OPTION);
if (confirmar == JOptionPane.YES_OPTION)//SI quiere modificar
{
            medicamentos.remove(i);
                  borrado = true;
                  String claved = JOptionPane.showInputDialog("cual es la nueva clave del producto");
                  String nombre = JOptionPane.showInputDialog("cual es el nuevo nombre del producto");
            int precio = Integer.parseInt(JOptionPane.showInputDialog("cual es el nuevo precio del producto"));
            int existencia = Integer.parseInt(JOptionPane.showInputDialog("Cuántos productos hay en existencia"));
                 
                  Medicamentos nuevoMed = new Medicamentos(claved,nombre, precio, existencia);
            medicamentos.add(nuevoMed);

       
      borrado = true;
}//
               else{
   JOptionPane.showMessageDialog(null, "NO se encontro Medicamento con la clave: " + clave, "Baja de Medicamentos",
JOptionPane.INFORMATION_MESSAGE);
      }
            }
      }    
      }
   }*/
}
El método de modificacion lo puse en comentario porque la quiero mover a otra clase

janegg

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 18
    • Ver Perfil
Y esta es la nueva clase que cree: Modificacion
Código: [Seleccionar]
import javax.swing.JOptionPane;
import java.io.*;
import java.util.ArrayList;

public class Modificacion
{
   private File archivo = new File("archiyect.txt");
private ArrayList<Medicamentos> medicamentos = new ArrayList<>();

public Modificacion()
{
/*
* El constructor de Metodos lo que hará es comprobar si ya existe un
* archivo con datos de Medicamentos ya creado.
* Si existe, recuperará estos datos, creará objetos Medicamentos y los
* pasará al ArrayList desde donde podremos trabajar con ellos.
* Si no existe, no hará nada, tendremos un ArrayList vacio listo para
* que podamos hacer las primeras altas.
*/
if (archivo.exists())
{
try {
BufferedReader leer = new BufferedReader(new FileReader(archivo));
String linea = leer.readLine();
while(linea != null)
{
/*
* Separamos los atributos del Medicamento de la linea que hemos leido
* En la linea los atributos estan separados por un doble guion "--"
* La linea contendrá los 8 atributos correspondientes a un Medicamento.
* Sin embargo, los 4 últimos es posible que no tengan datos validos, si no que
* puede que contengan valores null y 0, ya que los únicos atributos que son
* de obligatoria cumplimentación son los primeros 4.
*/

String[] atributos = linea.split("--");
//Los 4 atributos obligatorios
String clave = atributos[0];
String nombre = atributos[1];
int precio = Integer.parseInt(atributos[2]);
int existencia = Integer.parseInt(atributos[3]);

/*
* Ahora recogemos los 4 atributos opcionales.
* Los de tipo String, si no fueron cumplimentados,
* tendrían valor null  y en el archivo de texto se
* habrá escrito la palabra "null". Sin embargo,
* al leer del archivo estamos recibiendo un String
* con el texto "null". No podemos pasar este texto
* directamente al atributo, sino que en este caso
* debemos pasar el valor null, que no es lo mismo
* que un string con el texto "null". Son cosas distintas.
*/
String nombreGenerico;
if (atributos[4].equals("null"))//Este atributo tenía valor null cuando se guardo en el archivo
nombreGenerico = null;
else
nombreGenerico = atributos[4];

int caducidad = Integer.parseInt(atributos[5]);

String formaFarmaceutica;
if (atributos[6].equals("null"))
formaFarmaceutica = null;
else
formaFarmaceutica = atributos[6];

int concentracion = Integer.parseInt(atributos[7]);

/*
* Ya tenemos los 8 atributos.
* Podemos añadir al ArrayList un nuevo Medicamento.
*/

medicamentos.add(new Medicamentos(clave, nombre, precio, existencia, nombreGenerico,
caducidad, formaFarmaceutica, concentracion));
//Medicamento añadido, leemos una nueva linea y si contiene datos, se repetirá este proceso
linea = leer.readLine();
}
leer.close();
//Lectura concluida.
//Podemos informar por pantalla cuantos Medicamentos hemos recuperado del archivo
JOptionPane.showMessageDialog(null, "Cantidad de Medicamentos recuperados: " + medicamentos.size(),
"Datos Leidos", JOptionPane.INFORMATION_MESSAGE);
} catch (Exception ex)
{
JOptionPane.showMessageDialog(null, "No se pudo leer datos del archivo: " + archivo.getAbsolutePath(),
"Error de Lectura", JOptionPane.WARNING_MESSAGE);
}
}
}
   
private String mensajeMedicamento(Medicamentos m)
{
return "Clave: " + m.getClave()
+ "\nNombre: " + m.getNombre()
+ "\nPrecio: " + m.getPrecio()
+ "\nExistencias: " + m.getExistencia()
+ "\nNombre Generico: " + m.getNombregenerico()
+ "\nCaducidad: " + m.getCaducidad()
+ "\nForma Farmaceutica: " + m.getFormafarmaceutica()
+ "\nConcentracion: " + m.getConcentracion();
}


public void modificar()throws FileNotFoundException,IOException
   {
   if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
String clave = JOptionPane.showInputDialog("Introduzca la clave del Medicamento para modificar:");
boolean encontrado = false;//Para controlar si lo hemos encontrado
boolean borrado = false;//Para controla si el usuario ha decidido eliminarlo
for (int i = 0; i < medicamentos.size(); i++)
{
if (medicamentos.get(i).getClave().equalsIgnoreCase(clave))
{
encontrado = true;
String mensaje = mensajeMedicamento(medicamentos.get(i)) + "\n\n¿Desea modificar este medicamento?";
int confirmar = JOptionPane.showConfirmDialog(null, mensaje, "Confirmar Baja", JOptionPane.YES_NO_OPTION);
if (confirmar == JOptionPane.YES_OPTION)//SI quiere modificar
{
            medicamentos.remove(i);
                  borrado = true;
                  String claved = JOptionPane.showInputDialog("cual es la nueva clave del producto");
                  String nombre = JOptionPane.showInputDialog("cual es el nuevo nombre del producto");
            int precio = Integer.parseInt(JOptionPane.showInputDialog("cual es el nuevo precio del producto"));
            int existencia = Integer.parseInt(JOptionPane.showInputDialog("Cuántos productos hay en existencia"));
                 
                  Medicamentos nuevoMed = new Medicamentos(claved,nombre, precio, existencia);
            medicamentos.add(nuevoMed);

        /* try{
        BufferedWriter escribir = new BufferedWriter(new FileWriter(archivo, true));
        escribir.write(nuevoMed.toString());
        escribir.newLine();
        escribir.close();
            }catch(IOException e){
         JOptionPane.showMessageDialog(null, "No se pudo escribir datos en archivo: " + archivo.getAbsolutePath(),
   "Error de Escritura", JOptionPane.WARNING_MESSAGE);
                                 }*/

      borrado = true;
}//
               else{
   JOptionPane.showMessageDialog(null, "NO se encontro Medicamento con la clave: " + clave, "Baja de Medicamentos",
JOptionPane.INFORMATION_MESSAGE);
      }
            }
      }    
      }
   }
}

y pues en la Implementacion sólo invoqué la instancia de Modificacion y cambie el nombre:
Código: [Seleccionar]
import java.io.*;
import javax.swing.JOptionPane;
public class Implementacion
{

public static void main(String args[])throws FileNotFoundException, IOException
{     
//Inicializamos el objeto que contiene y gestiona todos los datos y funciones del programa
Metodos metodos = new Metodos();
      Modificacion mod = new Modificacion();

String opcions;
int opcion;
do{
opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Listado de productos\n 3.Consulta de productos\n 4.Bajas\n 5.Modificacion\n 6.SALIR\n");
//opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Consulta productos\n 3.Baja porductos\n 4.Modificacion de un producto\n 5.Listado de productos\n 6. Salir\n ");
opcion=Integer.parseInt (opcions);
switch(opcion)
{
case 1:
metodos.altas();
break;
case 2:
metodos.listado();
break;
case 3:
String opcionl;
int opc;
do{
opcionl=JOptionPane.showInputDialog ("Menu\n 1.Busqueda por clave\n 2.Busqueda por nombre\n 3.SALIR");
opc=Integer.parseInt(opcionl);
switch(opc){
case 1:
metodos.consultasc();
break;
case 2:
metodos.consultasn();
break;
}
}while(opc!=3);
break;
case 4:
metodos.bajas();
break;
case 5:
mod.modificar();
  break;
            case 6:
JOptionPane.showMessageDialog(null, "FIN del programa");
break;
default:
JOptionPane.showMessageDialog(null, "Opcion invalida");

}while(opcion!=6);
}   
}

Espero me puedas ayudar, gracias!

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
Ahora no puedo probar lo que has hecho.

Pero intuyo que el problema está en que ahora hay dos ArrayList de Medicamentos en memoria, el que crea Metodos y el que está creando ahora tu nueva clase Modificacion.

Estos ArrayList no están sincronizados, así que a lo largo del programa tendrán datos distintos.

Cuando haces una modificación, estás cambiando el ArrayList de la clase Modificacion.
Pero si luego haces una consulta, estás consultando el ArrayList de la clase Metodos. Por eso no ves las modificaciones que haces.

Si quieres que varias clases modifiquen un mismo objeto, lo mejor es que ese objeto lo declares e incialices en un sitio donde luego puedas pasárselo por referencia (luego comentamos que significa esto) a estas clases y así todas están trabajando con el mismo objeto.

Creo que lo más cómodo es declararlo en Implementacion.
En esta clase ahora mismo, solo tenemos el metodo main().

Pero podemos añadirle atributos y un constructor si lo necesitamos, y eso es lo que vamos a hacer.
Código: [Seleccionar]
package farmaceutica;

import java.io.*;
import java.util.ArrayList;

import javax.swing.JOptionPane;
public class Implementacion
{

private File archivo = new File("c:\\prueba\\archiyect.txt");
private ArrayList<Medicamentos> medicamentos = new ArrayList<>();

public Implementacion()
{
if (archivo.exists())
{
try {
BufferedReader leer = new BufferedReader(new FileReader(archivo));
String linea = leer.readLine();
while(linea != null)
{
String[] atributos = linea.split("--");
//Los 4 atributos obligatorios
String clave = atributos[0];
String nombre = atributos[1];
int precio = Integer.parseInt(atributos[2]);
int existencia = Integer.parseInt(atributos[3]);

//Los 4 atributos opcionales
String nombreGenerico;
if (atributos[4].equals("null"))//Este atributo tenía valor null cuando se guardo en el archivo
nombreGenerico = null;
else
nombreGenerico = atributos[4];

int caducidad = Integer.parseInt(atributos[5]);

String formaFarmaceutica;
if (atributos[6].equals("null"))
formaFarmaceutica = null;
else
formaFarmaceutica = atributos[6];

int concentracion = Integer.parseInt(atributos[7]);

medicamentos.add(new Medicamentos(clave, nombre, precio, existencia, nombreGenerico,
caducidad, formaFarmaceutica, concentracion));
//Medicamento añadido, leemos una nueva linea y si contiene datos, se repetirá este proceso
linea = leer.readLine();
}
leer.close();
//Lectura concluida.
//Podemos informar por pantalla cuantos Medicamentos hemos recuperado del archivo
JOptionPane.showMessageDialog(null, "Cantidad de Medicamentos recuperados: " + medicamentos.size(),
"Datos Leidos", JOptionPane.INFORMATION_MESSAGE);
} catch (Exception ex)
{
JOptionPane.showMessageDialog(null, "No se pudo leer datos del archivo: " + archivo.getAbsolutePath(),
"Error de Lectura", JOptionPane.WARNING_MESSAGE);
}
}
}

public static void main(String args[])throws FileNotFoundException, IOException
{   
//Inicializamos implementacion, quien tiene el ArrayList de Medicamentos
Implementacion implementacion = new Implementacion();
//Inicializamos el objeto que contiene las funciones del programa
Metodos metodos = new Metodos(implementacion.medicamentos);//Recibe el ArrayList de Medicamentos.

String opcions;
int opcion;
do{
opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Listado de productos\n 3.Consulta de productos\n 4.Bajas\n 5.SALIR\n");
//opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Consulta productos\n 3.Baja porductos\n 4.Modificacion de un producto\n 5.Listado de productos\n 6. Salir\n ");
opcion=Integer.parseInt (opcions);
switch(opcion)
{
case 1:
metodos.altas();
break;
case 2:
metodos.listado();
break;
case 3:
String opcionl;
int opc;
do{
opcionl=JOptionPane.showInputDialog ("Menu\n 1.Busqueda por clave\n 2.Busqueda por nombre\n 3.SALIR");
opc=Integer.parseInt(opcionl);
switch(opc){
case 1:
metodos.consultasc();
break;
case 2:
metodos.consultasn();
break;
}
}while(opc!=3);
break;
case 4:
metodos.bajas();
break;
case 5:
JOptionPane.showMessageDialog(null, "FIN del programa");
break;
default:
JOptionPane.showMessageDialog(null, "Opcion invalida");

}while(opcion!=5);
}   
}


Añadimos dos atributos, el objeto File y el ArrayList.

Añadimos un constructor, que hace exactamente lo mismo que hacía el constructor de Metodos. Leerá el fichero de texto, si es que existe, recogerá los datos que contiene y añadirá los Medicamentos que encuentre al ArrayList.

Luego, en el metodo main(), lo primero que hacemos es instanciar a la clase Implementacion. Así su constructor creará el ArrayList.

Luego instanciamos la clase Metodos, solo que esta vez le vamos a pasar como argumento el ArrayList del objeto Implementación.
Así la clase Metodos trabajará con ESTE ArrayList, en lugar de trabajar con uno propio.
Fíjate que le estamos pasando el ArrayList sin necesidad de usar ningún getter o setter.
Estos es porque el método main() pertenece a la clase Implementacion, y por tanto puede ver y acceder directamente a sus atributos, sin tener que usar un metodo public void getArray() ni nada de esto


Luego, tendrías que instanciar tu clase Modificacion y al igual que con Metodos, pasarle el ArrayList de Implementacion.

Así ambas clases trabajaran con el MISMO ArrayList, y las modificaciones que haga uno, las verá el otro.

Ahora, hay que modificar la clase Metodos, ya que ahora mismo no está escrita para recibir un ArrayList externo.

Los cambios que hay que hacer son muy simples, tan solo hay que modificar su constructor.
Antes se encargaba de leer el archivo e inicializar el ArrayList. Esto ahora ya lo hace Implementacion, así que el constructor de Metodos lo único que tiene que hacer ahora es recibir el ArrayList y recogerlo para su atributo.

Código: [Seleccionar]
public class Metodos {

private File archivo = new File("c:\\prueba\\archiyect.txt");
private ArrayList<Medicamentos> medicamentos = new ArrayList<>();

public Metodos(ArrayList<Medicamentos> medicamentos)
{
this.medicamentos = medicamentos;
}

Y para tu clase Modificacion, habría que hacer exactamente lo mismo.

Y creo que con esto, debería funcionarte. Pruébalo y nos lo comentas.


Sobre lo que decía antes de para POR REFERENCIA.
Fíjate que las clases Metodos y Modificacion, aunque cada una declara su propio ArrayList como atributo, en realidad van a trabajar con un UNICO ArrayList, que es el que reciben desde la clase Implementacion

Esto es posible porque este objeto lo reciben POR REFERENCIA.
En programacion, cuando pasamos una variable u objeto a un método o a una clase, hay (principalmente) dos formas de hacerlo: POR REFERENCIA o POR VALOR

Pasar una variable u objeto (son lo mismo en realidad) por VALOR significa que lo que le estamos pasando a la clase/metodo, es una copia de esa variable.
Los cambios que hagamos a esa copia, NO tendrán ningún efecto en la variable original.

Pasar una variable por REFERENCIA significa que NO estamos pasando una copia, si no que lo que estamos pasando es la direccion de memoria donde se encuentra la variable original. Un "acceso directo" por así decirlo.
En este caso, los cambios que hagamos a esta variable, SI tienen efecto en la variable original, porque en realidad solo hay una.
No estariamos trabajando con una copia, sino con la original.

En Java, para bien o para mal... los objetos "complejos" SIEMPRE se pasan por REFERENCIA. No podemos escoger.
Por este motivo, las clases Metodos y Modificacion van a poder trabajar con el mismo ArrayList al mismo tiempo. Porque NO han recibido una copia, han recibido la direccion de memoria donde se encuentra este UNICO ArrayList

En cambio, cuando se trata de variables primitivas (int, char, double, byte...), en Java siempre se pasan por VALOR.
Esto significa que sí se recibe una COPIA del ORIGINAL. Así que si le hacemos un cambio a esta COPIA, tenemos que tener en cuenta que el ORIGINAL no va a cambiar.
Por tanto si queremos trabajar con los cambios que les hemos hecho a la COPIA, tenemos que retornarlo y recogerlos, porque el ORIGINAL no sabe nada de los cambios que hayamos hecho.


En otros lenguajes como C/C++, si podemos escoger de qué modo transmitimos las variables y objetos.
Esto nos da más poder, pero también más responsabilidad (ya lo decia el tio de Spiderman: "Un gran poder conlleva una gran responsabilidad" ).

Más responsabilidad porque si nos despistamos podemos incluso dejar datos en memoria perdidos sin ninguna referencia para encontrarlos, o tener referencias que apuntan a datos equivocados o invalidos.

Java no nos da tanto poder, pero a cambio se encarga de que no haya lios con las referencias y de limpiar datos que hayan podido quedar sin puntero que indique donde están, y en general, nos hace más fácil la vida a los que estamos aprendiendo programacion.
« Última modificación: 12 de Junio 2018, 13:37 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

janegg

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 18
    • Ver Perfil
Ohh sii entiendo, lo estoy checando y si compila bien con todas las modificaciones que me dijiste, el problema ahora es que guarda los registros en el archivo de texto, pero cuando quiero ver el listado(los registros) me manda el mensaje de que está vacío, entonces tendría que hacer lo mismo con todos los métodos?
Dejo las clases a las que hice las modificaciones:
Código: [Seleccionar]
import javax.swing.JOptionPane;
import java.io.*;
import java.util.ArrayList;

public class Metodos {

private File archivo = new File("archiyect.txt");
private ArrayList<Medicamentos> medicamentos = new ArrayList<>();

public Metodos(ArrayList<Medicamentos> medicamentos)
{
this.medicamentos = medicamentos;
}
public void altas() throws FileNotFoundException,IOException
{
/*
* Los Medicamentos tienen 8 atributos, pero para su creacion solo
* son obligatorios propocionar 4. En este ejemplo solo pediremos
* los 4 atributos obligatorios.
*/
String clave = JOptionPane.showInputDialog("Dame la clave del producto");
String nombre = JOptionPane.showInputDialog("Escribe el nombre del producto");
int precio = Integer.parseInt(JOptionPane.showInputDialog("Escribe el precio del producto"));
int existencia = Integer.parseInt(JOptionPane.showInputDialog("Cuántos productos hay en existencia"));
String nombregenerico = JOptionPane.showInputDialog("Cual es el nombre generico del medicamento");
      int caducidad = Integer.parseInt(JOptionPane.showInputDialog("Caducidad del producto"));
      String formafarmaceutica = JOptionPane.showInputDialog("Cual es la forma farmaceutica?");
      int concentracion =  Integer.parseInt(JOptionPane.showInputDialog("Concentracion en caso de tenerla"));
      /*
* Tenemos los 4 atributos.
* Crearemos un Medicamento y lo añadiremos al ArrayList.
* Luego, lo añadiremos al archivo de texto en disco.
*/
Medicamentos nuevoMed = new Medicamentos(clave, nombre, precio, existencia, nombregenerico, caducidad,
      formafarmaceutica, concentracion);
medicamentos.add(nuevoMed);

try{
BufferedWriter escribir = new BufferedWriter(new FileWriter(archivo, true));
escribir.write(nuevoMed.toString());
escribir.newLine();
escribir.close();
}catch(IOException e){
JOptionPane.showMessageDialog(null, "No se pudo escribir datos en archivo: " + archivo.getAbsolutePath(),
"Error de Escritura", JOptionPane.WARNING_MESSAGE);
}
}

/**
* Este metodo contruye un String con todos los datos de un
* Medicamento para ser mostrado en pantalla.
* Es útil porque puede ser utilizado para las funciones
* de listado, búsqueda por clave, busqueda por nombre..
* @param m Objeto Medicamentos que queremos mostrar.
* @return Cadena String con todos los datos
*/
private String mensajeMedicamento(Medicamentos m)
{
return "Clave: " + m.getClave()
+ "\nNombre: " + m.getNombre()
+ "\nPrecio: " + m.getPrecio()
+ "\nExistencias: " + m.getExistencia()
+ "\nNombre Generico: " + m.getNombregenerico()
+ "\nCaducidad: " + m.getCaducidad()
+ "\nForma Farmaceutica: " + m.getFormafarmaceutica()
+ "\nConcentracion: " + m.getConcentracion();
}

public void listado()
{
/*
* Recorremos el ArrayList y por cada Medicamento existente
* construimos un mensaje con los datos y lo mostramos en un
* Dialogo de Confirmacion.
* El usuario tiene la oportunidad de finalizar el listado pulsando
* el boton NO de este dialogo.
* Antes de nada, por supuesto, hemos de comprobar si existen medicamentos
* ya registrados
*/
if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
for (int i = 0; i < medicamentos.size(); i++)
{
/*
* Para mostrar el medicamento usamos el String que nos devuelve el metodo
* mensajeMedicamento() y además le añadimos otra linea indicando al usuario
* que puede detener el listado pulsando el boton NO de la ventana de dialogo.
* Esta ventana, en su título superior, además mostrará el número de posicion
* que ocupa este Medicamento en el ArrayList y el total que hay.
* Un mensaje tipo ---> Medicamento nº 4/30
* Así el usuario tendrá una idea de cuantos Medicamentos quedan por listar.
*/
String mensaje = mensajeMedicamento(medicamentos.get(i)) + "\n\n¿Desea seguir visualizando el listado?";

int seguir = JOptionPane.showConfirmDialog(null, mensaje, "Medicamento nº " + (i+1) + "/" + medicamentos.size(), JOptionPane.YES_NO_OPTION);

if (seguir == JOptionPane.NO_OPTION)//Usuario NO quiere seguir con el listado, "rompemos" el bucle
break;
}
}
}
//CONSULTA POR CLAVE
public void consultasc()
{
if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
String clave = JOptionPane.showInputDialog("Introduzca clave del medicamento a buscar:");

/*
* Recorremos el ArrayList mediante un bucle FOR EACH para buscar el Medicamento con
* la clave que nos han indicado.
* Si lo encontramos, mostramos sus datos y detenemos el bucle de búsqueda.
* Si no lo encontramos, habría que informar al usuario de que no existe dicha clave.
* Para controlar si hemos encontrado o no el Medicamento, podemos usar una variable
* booleana. Esta variable comenzará con valor false.
* Si lo encontramos, la pondremos a true.
* Al terminar el bucle de busqueda, si esta variable conserva el valor false inicial,
* sabremos que el Medicamento no fue encontrado e informaremos al usuario.
*/
boolean encontrado = false;
for (Medicamentos m:medicamentos)
{
if (m.getClave().equalsIgnoreCase(clave))
{
encontrado = true;//¡¡Lo hemos encontrado!!
JOptionPane.showMessageDialog(null, mensajeMedicamento(m), "Mostrando medicamento", JOptionPane.INFORMATION_MESSAGE);
}
}
//Bucle de busqueda terminado, hemos de comprobar si fue encontrado el medicamento o no
if (!encontrado)
JOptionPane.showMessageDialog(null, "No se encontro medicamento con clave: " + clave, "Mostrando medicamento", JOptionPane.INFORMATION_MESSAGE);
}

}

//CONSULTA POR NOMBRE
public void consultasn()
{
//consultas por nombre
      if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
String nombre = JOptionPane.showInputDialog("Introduzca nombre del medicamento a buscar:");

/*
* Recorremos el ArrayList mediante un bucle FOR EACH para buscar el Medicamento con
* el nombre que nos han indicado.
* Si lo encontramos, mostramos sus datos y detenemos el bucle de búsqueda.
* Si no lo encontramos, habría que informar al usuario de que no existe dicho nombre.
* Para controlar si hemos encontrado o no el Medicamento, podemos usar una variable
* booleana. Esta variable comenzará con valor false.
* Si lo encontramos, la pondremos a true.
* Al terminar el bucle de busqueda, si esta variable conserva el valor false inicial,
* sabremos que el Medicamento no fue encontrado e informaremos al usuario.
*/
boolean encontrado = false;
for (Medicamentos m:medicamentos)
{
if (m.getNombre().equalsIgnoreCase(nombre))
{
encontrado = true;//¡¡Lo hemos encontrado!!
JOptionPane.showMessageDialog(null, mensajeMedicamento(m), "Mostrando medicamento", JOptionPane.INFORMATION_MESSAGE);
}
}
//Bucle de busqueda terminado, hemos de comprobar si fue encontrado el medicamento o no
if (!encontrado)
JOptionPane.showMessageDialog(null, "No se encontro medicamento con ese nombre: " + nombre, "Mostrando medicamento", JOptionPane.INFORMATION_MESSAGE);
}
     
}


public void bajas()throws FileNotFoundException,IOException
{
/*
* El metodo para hacer bajas es muy parecido al metodo de consulta por clave.
* Solo que esta vez al encontrar el medicamento, este ha de ser eliminado del
* ArrayList y también del fichero de texto donde guardamos los datos.
* Borrar del ArrayList se hace con una sencilla instruccion.
* Borrar la linea de datos del archivo de texto, es un poco más laborioso.
* Para facilitar la tarea, lo ideal es eliminar el archivo por completo
* y volver a crearlo de nuevo con todos los Medicamentos contenidos en el
* ArrayList, donde ya no estará el Medicamento que hemos dado de baja.
*/
if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
String clave = JOptionPane.showInputDialog("Introduzca clave de Medicamento a eliminar:");
boolean encontrado = false;//Para controlar si lo hemos encontrado
boolean borrado = false;//Para controla si el usuario ha decidido eliminarlo
for (int i = 0; i < medicamentos.size(); i++)
{
if (medicamentos.get(i).getClave().equalsIgnoreCase(clave))
{
encontrado = true;
String mensaje = mensajeMedicamento(medicamentos.get(i)) + "\n\n¿Desea dar de baja?";
int confirmar = JOptionPane.showConfirmDialog(null, mensaje, "Confirmar Baja", JOptionPane.YES_NO_OPTION);
if (confirmar == JOptionPane.YES_OPTION)//SI quiere dar de baja
{
//Eliminamos del ArrayList
medicamentos.remove(i);
borrado = true;
}
}
}
/*
* Bucle de busqueda terminado ahora comprobamos si el Medicamento fue encontrado o no.
* Si no fue encontrado, informamos al usuario con un mensaje
* Si fue encontrado y eliminado guardaremos los datos actualizados en el archivo de texto.
* Para crear este archivo habrá que recorrer de nuevo el ArrayList y añadir una linea de texto
* por cada Medicamento que contenga.
*/
if (encontrado && borrado)
{
try {
//Intentamos borrar archivo actual
if (archivo.delete())
{
//Archivo borrado, creamos uno nuevo actualizado
BufferedWriter escribir = new BufferedWriter(new FileWriter(archivo, true));
for (Medicamentos m:medicamentos)
{
escribir.write(m.toString());
escribir.newLine();
}
escribir.close();
JOptionPane.showMessageDialog(null, "Medicamento eliminado.\nLos cambios se han guardado", "Baja de Medicamento",
JOptionPane.INFORMATION_MESSAGE);
}
else//Por algun motivo, no se pudo borrar archivo
{
JOptionPane.showMessageDialog(null, "Error de acceso a archivo.\nLos cambios no han sido guardados", "Baja de Medicamento",
JOptionPane.WARNING_MESSAGE);
}
} catch(Exception ex) {
JOptionPane.showMessageDialog(null, "Error de acceso a archivo\nTipo de error: " + ex.getLocalizedMessage());
}
}
else if(!encontrado)//No fue encontrado
{
JOptionPane.showMessageDialog(null, "NO se encontro Medicamento con la clave: " + clave, "Baja de Medicamentos",
JOptionPane.INFORMATION_MESSAGE);
}

}
}
}

Código: [Seleccionar]
import javax.swing.JOptionPane;
import java.io.*;
import java.util.ArrayList;

public class Modificacion
{
   private File archivo = new File("archiyect.txt");
private ArrayList<Medicamentos> medicamentos = new ArrayList<>();

   public Modificacion(ArrayList<Medicamentos> medicamentos)
{
this.medicamentos = medicamentos;
}
private String mensajeMedicamento(Medicamentos m)
{
return "Clave: " + m.getClave()
+ "\nNombre: " + m.getNombre()
+ "\nPrecio: " + m.getPrecio()
+ "\nExistencias: " + m.getExistencia()
+ "\nNombre Generico: " + m.getNombregenerico()
+ "\nCaducidad: " + m.getCaducidad()
+ "\nForma Farmaceutica: " + m.getFormafarmaceutica()
+ "\nConcentracion: " + m.getConcentracion();
}


public void modificar()throws FileNotFoundException,IOException
   {
   if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
String clave = JOptionPane.showInputDialog("Introduzca la clave del Medicamento para modificar:");
boolean encontrado = false;//Para controlar si lo hemos encontrado
boolean borrado = false;//Para controla si el usuario ha decidido eliminarlo
for (int i = 0; i < medicamentos.size(); i++)
{
if (medicamentos.get(i).getClave().equalsIgnoreCase(clave))
{
encontrado = true;
String mensaje = mensajeMedicamento(medicamentos.get(i)) + "\n\n¿Desea modificar este medicamento?";
int confirmar = JOptionPane.showConfirmDialog(null, mensaje, "Confirmar Baja", JOptionPane.YES_NO_OPTION);
if (confirmar == JOptionPane.YES_OPTION)//SI quiere modificar
{
            medicamentos.remove(i);
                  borrado = true;
                  String claved = JOptionPane.showInputDialog("cual es la nueva clave del producto");
                  String nombre = JOptionPane.showInputDialog("cual es el nuevo nombre del producto");
            int precio = Integer.parseInt(JOptionPane.showInputDialog("cual es el nuevo precio del producto"));
            int existencia = Integer.parseInt(JOptionPane.showInputDialog("Cuántos productos hay en existencia"));
                 
                  Medicamentos nuevoMed = new Medicamentos(claved,nombre, precio, existencia);
            medicamentos.add(nuevoMed);

        /* try{
        BufferedWriter escribir = new BufferedWriter(new FileWriter(archivo, true));
        escribir.write(nuevoMed.toString());
        escribir.newLine();
        escribir.close();
            }catch(IOException e){
         JOptionPane.showMessageDialog(null, "No se pudo escribir datos en archivo: " + archivo.getAbsolutePath(),
   "Error de Escritura", JOptionPane.WARNING_MESSAGE);
                                 }*/

      borrado = true;
}//
               else{
   JOptionPane.showMessageDialog(null, "NO se encontro Medicamento con la clave: " + clave, "Baja de Medicamentos",
JOptionPane.INFORMATION_MESSAGE);
      }
            }
      }    
      }
   }
}

janegg

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 18
    • Ver Perfil
y la Implementacion
Código: [Seleccionar]
import java.io.*;
import java.util.ArrayList;

import javax.swing.JOptionPane;
public class Implementacion
{

private File archivo = new File("c:\\prueba\\archiyect.txt");
private ArrayList<Medicamentos> medicamentos = new ArrayList<>();

public Implementacion()
{
if (archivo.exists())
{
try {
BufferedReader leer = new BufferedReader(new FileReader(archivo));
String linea = leer.readLine();
while(linea != null)
{
String[] atributos = linea.split("--");
//Los 4 atributos obligatorios
String clave = atributos[0];
String nombre = atributos[1];
int precio = Integer.parseInt(atributos[2]);
int existencia = Integer.parseInt(atributos[3]);

//Los 4 atributos opcionales
String nombreGenerico;
if (atributos[4].equals("null"))//Este atributo tenía valor null cuando se guardo en el archivo
nombreGenerico = null;
else
nombreGenerico = atributos[4];

int caducidad = Integer.parseInt(atributos[5]);

String formaFarmaceutica;
if (atributos[6].equals("null"))
formaFarmaceutica = null;
else
formaFarmaceutica = atributos[6];

int concentracion = Integer.parseInt(atributos[7]);

medicamentos.add(new Medicamentos(clave, nombre, precio, existencia, nombreGenerico,
caducidad, formaFarmaceutica, concentracion));
//Medicamento añadido, leemos una nueva linea y si contiene datos, se repetirá este proceso
linea = leer.readLine();
}
leer.close();
//Lectura concluida.
//Podemos informar por pantalla cuantos Medicamentos hemos recuperado del archivo
JOptionPane.showMessageDialog(null, "Cantidad de Medicamentos recuperados: " + medicamentos.size(),
"Datos Leidos", JOptionPane.INFORMATION_MESSAGE);
} catch (Exception ex)
{
JOptionPane.showMessageDialog(null, "No se pudo leer datos del archivo: " + archivo.getAbsolutePath(),
"Error de Lectura", JOptionPane.WARNING_MESSAGE);
}
}
}

public static void main(String args[])throws FileNotFoundException, IOException
{   
//Inicializamos implementacion, quien tiene el ArrayList de Medicamentos
Implementacion implementacion = new Implementacion();
//Inicializamos el objeto que contiene las funciones del programa
Metodos metodos = new Metodos(implementacion.medicamentos);//Recibe el ArrayList de Medicamentos.
      Modificacion modifica = new Modificacion(implementacion.medicamentos);
     
String opcions;
int opcion;
do{
opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Listado de productos\n 3.Consulta de productos\n 4.Bajas\n 5. Modificacion 6.SALIR\n");
//opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Consulta productos\n 3.Baja porductos\n 4.Modificacion de un producto\n 5.Listado de productos\n 6. Salir\n ");
opcion=Integer.parseInt (opcions);
switch(opcion)
{
case 1:
metodos.altas();
break;
case 2:
metodos.listado();
break;
case 3:
String opcionl;
int opc;
do{
opcionl=JOptionPane.showInputDialog ("Menu\n 1.Busqueda por clave\n 2.Busqueda por nombre\n 3.SALIR");
opc=Integer.parseInt(opcionl);
switch(opc){
case 1:
metodos.consultasc();
break;
case 2:
metodos.consultasn();
break;
}
}while(opc!=3);
break;
case 4:
metodos.bajas();
break;
case 5:
            modifica.modificar();
break;
         case 6:
JOptionPane.showMessageDialog(null, "FIN del programa");
break;
default:
JOptionPane.showMessageDialog(null, "Opcion invalida");

}while(opcion!=5);
}   
}

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
Hola compi.

Hay unos detalles que fallan.

El más importante, que supongo que es por lo que te salen vacio el archivo, es que en Implementacion estás usando la ruta de archivo que yo uso en mi ejercicio.
Código: [Seleccionar]
private File archivo = new File("c:\\prueba\\archiyect.txt");
En las otras clases, estás usando tu ruta habitual:
Código: [Seleccionar]
private File archivo = new File("archiyect.txt");
Por eso no ves los cambios.
Corrigelo para que todos tengan la misma ruta de archivo.
Incluso si quisieras, igual que a Metodo y Modificacion les estamos pasando a su constructor el ArrayList que deben usar, también se les podría pasar el objeto File que deben usar.
Así solo tendrías que declarar una vez la ruta en Implementacion y el resto lo recibirían de esta.


Otra cosa que faltaría es que en Modificacion, también se han de escribir los cambios en el archivo de texto.
Se procedería igual que en Bajas, borramos el archivo actual, y volvemos a crearlo con los nuevos datos.
Te pongo aquí como lo he hecho yo:
Código: [Seleccionar]
package farmaceutica;

import javax.swing.JOptionPane;
import java.io.*;
import java.util.ArrayList;

public class Modificacion
{
private File archivo = new File("c:\\prueba\\archiyect.txt");
private ArrayList<Medicamentos> medicamentos = new ArrayList<>();

public Modificacion(ArrayList<Medicamentos> medicamentos)
{
this.medicamentos = medicamentos;
}
private String mensajeMedicamento(Medicamentos m)
{
return "Clave: " + m.getClave()
+ "\nNombre: " + m.getNombre()
+ "\nPrecio: " + m.getPrecio()
+ "\nExistencias: " + m.getExistencia()
+ "\nNombre Generico: " + m.getNombregenerico()
+ "\nCaducidad: " + m.getCaducidad()
+ "\nForma Farmaceutica: " + m.getFormafarmaceutica()
+ "\nConcentracion: " + m.getConcentracion();
}


public void modificar()throws FileNotFoundException,IOException
{
if (medicamentos.isEmpty())
JOptionPane.showMessageDialog(null, "No hay Medicamentos registrados");
else
{
String clave = JOptionPane.showInputDialog("Introduzca la clave del Medicamento para modificar:");
boolean encontrado = false;//Para controlar si lo hemos encontrado
for (int i = 0; i < medicamentos.size(); i++)
{
if (medicamentos.get(i).getClave().equalsIgnoreCase(clave))
{
encontrado = true;
String mensaje = mensajeMedicamento(medicamentos.get(i)) + "\n\n¿Desea modificar este medicamento?";
int confirmar = JOptionPane.showConfirmDialog(null, mensaje, "Confirmar Modificacion", JOptionPane.YES_NO_OPTION);
if (confirmar == JOptionPane.YES_OPTION)//SI quiere modificar
{
medicamentos.remove(i);
String claved = JOptionPane.showInputDialog("cual es la nueva clave del producto");
String nombre = JOptionPane.showInputDialog("cual es el nuevo nombre del producto");
int precio = Integer.parseInt(JOptionPane.showInputDialog("cual es el nuevo precio del producto"));
int existencia = Integer.parseInt(JOptionPane.showInputDialog("Cuántos productos hay en existencia"));

Medicamentos nuevoMed = new Medicamentos(claved,nombre, precio, existencia);
medicamentos.add(nuevoMed);

/*
* También podría hacer sin necesida de borrar --> .remove()
* y luego añadir uno nuevo --> .add()
*
* Se podría modificar directamente los atributos del
* objeto almacenado en el ArrayLis:
*
* medicamentos.get(i).setClave(claved);
* medicamentos.get(i).setNombre(nombre);
* etc...
*
*/

//Puesto que ha habido una modificacion, esta ha de guardarse en el archivo texto.
//Como hacíamos en las bajas, lo más fácil es eliminar el archivo y volver a crearlo
//con los nuevos datos.

try{
if (archivo.delete())
{
BufferedWriter escribir = new BufferedWriter(new FileWriter(archivo, true));
for (Medicamentos m:medicamentos)
{
escribir.write(m.toString());
escribir.newLine();
}
escribir.close();
JOptionPane.showMessageDialog(null, "Medicamento Modificado.\nLos cambios se han guardado", "Modificacion de Medicamento",
JOptionPane.INFORMATION_MESSAGE);
}
else//Por algun motivo, no se pudo borrar archivo
{
JOptionPane.showMessageDialog(null, "Error de acceso a archivo.\nLos cambios no han sido guardados", "Modificacion de Medicamento",
JOptionPane.WARNING_MESSAGE);
}
}catch(IOException e){
JOptionPane.showMessageDialog(null, "No se pudo escribir datos en archivo: " + archivo.getAbsolutePath(),
"Error de Escritura", JOptionPane.WARNING_MESSAGE);
}

}

}
}//Fin bucle FOR

if (!encontrado)//Tras recorrer todos los Medicamentos, no se ha encontrado lo que se buscaba
JOptionPane.showMessageDialog(null, "NO se encontro Medicamento con la clave: " + clave, "Baja de Medicamentos",
JOptionPane.INFORMATION_MESSAGE);
}
}
}


También he puesto un comentario explicando que tenemos dos formas de modificar un medicamento.
Una es como tu lo has hecho, lo borramos del ArrayList, pedimos datos y volvemos a crear uno nuevo.

La otra forma sería pedir datos y usarlos para cambiar los atributos directamente en el objeto Medicamento guardado en el ArrayList, usando sus correspondientes setters...

En ambos casos, habría que guardar luego en fichero texto.

Y creo que ya está. Esas dos cositas era lo que fallaba, sobre todo lo la ruta del archivo, ya que estabamos leyendo uno, pero luego guardando en otro.
Por eso siempre te salía vacío.
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

janegg

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 18
    • Ver Perfil
Ayy no me había fijado en ese pequeño GRAN detalle  :-\
ya hice los cambios, funciona! Dividiré los métodos en clase, espero no tener que molestarte más!
Gracias compi <3

janegg

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 18
    • Ver Perfil
Disculpa en esta parte del código para que en la clave solo acepte caracteres, tengo un ciclo, pero solo me lo acepta sin el ciclo do, ya que poniéndolo dice que no encuentra la variable, pero tengo que ponerlo para que repita las veces que sea necesaria hasta que se ingrese una clave solo con caracteres :S
Código: [Seleccionar]
import javax.swing.JOptionPane;
import java.io.*;
import java.util.ArrayList;

public class AltasListado {

private File archivo = new File("archiyect.txt");
private ArrayList<Medicamentos> medicamentos = new ArrayList<>();

public AltasListado(ArrayList<Medicamentos> medicamentos)
{
this.medicamentos = medicamentos;
}

public void altas() throws FileNotFoundException,IOException
{
      boolean bandera = false;
      boolean cm, cm2, cm3, cm4, cm5,cm6;

do{
      String clave = JOptionPane.showInputDialog("Dame la clave del producto");
      cm = clave.matches("([a-z]|[A-Z]|[Ñ,ñ]|\\s)+");
        if(cm == false)
          {
            JOptionPane.showMessageDialog(null,"Clave no valida","ERROR",JOptionPane.ERROR_MESSAGE);
                bandera = false;
           }
         else
         {
            bandera = true;
         }
        }while(bandera != true);
Medicamentos nuevoMed = new Medicamentos(clave, nombre, precio, existencia, nombregenerico, caducidad,
      formafarmaceutica, concentracion);
medicamentos.add(nuevoMed);

try{
BufferedWriter escribir = new BufferedWriter(new FileWriter(archivo, true));
escribir.write(nuevoMed.toString());
escribir.newLine();
escribir.close();
}catch(IOException e){
JOptionPane.showMessageDialog(null, "No se pudo escribir datos en archivo: " + archivo.getAbsolutePath(),
"Error de Escritura", JOptionPane.WARNING_MESSAGE);
}
}
private String mensajeMedicamento(Medicamentos m)
{
return "Clave: " + m.getClave()
+ "\nNombre: " + m.getNombre()
+ "\nPrecio: " + m.getPrecio()
+ "\nExistencias: " + m.getExistencia()
+ "\nNombre Generico: " + m.getNombregenerico()
+ "\nCaducidad: " + m.getCaducidad()
+ "\nForma Farmaceutica: " + m.getFormafarmaceutica()
+ "\nConcentracion: " + m.getConcentracion();
}
}

janegg

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 18
    • Ver Perfil
Bueno he encontrado otra alternativa, que es declarando las variables como string

janegg

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 18
    • Ver Perfil
Holaa
Para no tener tantas lineas de codigo en la clase Implementacion, pensaba pasarlo a otra clase, pero como Medicamentos está privado como podría pasarselo a la clase principal main?
Recuerdo que me comentabas algo anteriormente asi : "Estos es porque el método main() pertenece a la clase Implementacion, y por tanto puede ver y acceder directamente a sus atributos, sin tener que usar un metodo public void getArray() ni nada de esto


Si la clase implementación no perteneciera al metodo main cómo lo podría invocar??
Clase Implementacion
Código: [Seleccionar]
import java.io.*;
import java.util.ArrayList;

import javax.swing.JOptionPane;
public class Implementacion
{

private File archivo = new File("archiyect.txt");
private ArrayList<Medicamentos> medicamentos = new ArrayList<>();

public Implementacion()
{
       /* El constructor de Implementacion lo que hará es comprobar si ya existe un
* archivo con datos de Medicamentos ya creado.
* Si existe, recuperará estos datos, creará objetos Medicamentos y los
* pasará al ArrayList desde donde podremos trabajar con ellos.
* Si no existe, no hará nada, tendremos un ArrayList vacio listo para
* que podamos hacer las primeras altas.
       */
if (archivo.exists())
{
try {
BufferedReader leer = new BufferedReader(new FileReader(archivo));
String linea = leer.readLine();
while(linea != null)
{
/*
* Separamos los atributos del Medicamento de la linea que hemos leido
* En la linea los atributos estan separados por un doble guion "--"
* La linea contendrá los 8 atributos correspondientes a un Medicamento.
* Sin embargo, los 4 últimos es posible que no tengan datos validos, si no que
* puede que contengan valores null y 0, ya que los únicos atributos que son
* de obligatoria cumplimentación son los primeros 4.
*/
               String[] atributos = linea.split("--");
//Los 4 atributos obligatorios
String clave = atributos[0];
String nombre = atributos[1];
String precio = atributos[2];
String existencia = atributos[3];

//Los 4 atributos opcionales
               /*
* Ahora recogemos los 4 atributos opcionales.
* Los de tipo String, si no fueron cumplimentados,
* tendrían valor null  y en el archivo de texto se
* habrá escrito la palabra "null". Sin embargo,
* al leer del archivo estamos recibiendo un String
* con el texto "null". No podemos pasar este texto
* directamente al atributo, sino que en este caso
* debemos pasar el valor null, que no es lo mismo
* que un string con el texto "null". Son cosas distintas.
*/

String nombreGenerico;
if (atributos[4].equals("null"))//Este atributo tenía valor null cuando se guardo en el archivo
nombreGenerico = null;
else
nombreGenerico = atributos[4];

               String caducidad;
if (atributos[5].equals("null"))
caducidad= null;
else
caducidad = atributos[5];
               
//int caducidad = Integer.parseInt(atributos[5]);

String formaFarmaceutica;
if (atributos[6].equals("null"))
formaFarmaceutica = null;
else
formaFarmaceutica = atributos[6];

               String concentracion;
if (atributos[7].equals("null"))
concentracion = null;
else
concentracion = atributos[6];
               
//int concentracion = Integer.parseInt(atributos[7]);
               /*
* Ya tenemos los 8 atributos.
* Podemos añadir al ArrayList un nuevo Medicamento.
*/

medicamentos.add(new Medicamentos(clave, nombre, precio, existencia, nombreGenerico,
caducidad, formaFarmaceutica, concentracion));
//Medicamento añadido, leemos una nueva linea y si contiene datos, se repetirá este proceso
linea = leer.readLine();
}
leer.close();
//Lectura concluida.
//Podemos informar por pantalla cuantos Medicamentos hemos recuperado del archivo
JOptionPane.showMessageDialog(null, "Cantidad de Medicamentos recuperados: " + medicamentos.size(),
"Datos Leidos", JOptionPane.INFORMATION_MESSAGE);
} catch (Exception ex)
{
JOptionPane.showMessageDialog(null, "No se pudo leer datos del archivo: " + archivo.getAbsolutePath(),
"Error de Lectura", JOptionPane.WARNING_MESSAGE);
}
}
}

/*public static void main(String args[])throws FileNotFoundException, IOException
{   
//Inicializamos implementacion, quien tiene el ArrayList de Medicamentos
Implementacion implementacion = new Implementacion();
//Inicializamos el objeto que contiene las funciones del programa
AltasListado al = new AltasListado(implementacion.medicamentos);//Recibe el ArrayList de Medicamentos.
      Modificacion modifica = new Modificacion(implementacion.medicamentos);
      Consultas consultas = new Consultas(implementacion.medicamentos);
      Bajas bajas = new Bajas(implementacion.medicamentos);
     
String opcions;
int opcion;
do{
opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Listado de productos\n 3.Consulta de productos\n 4.Bajas\n 5. Modificacion 6.SALIR\n");
//opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Consulta productos\n 3.Baja porductos\n 4.Modificacion de un producto\n 5.Listado de productos\n 6. Salir\n ");
opcion=Integer.parseInt (opcions);
switch(opcion)
{
case 1:
al.altas();
break;
case 2:
al.listado();
break;
case 3:
String opcionl;
int opc;
do{
opcionl=JOptionPane.showInputDialog ("Menu\n 1.Busqueda por clave\n 2.Busqueda por nombre\n 3.SALIR");
opc=Integer.parseInt(opcionl);
switch(opc){
case 1:
consultas.consultasc();
break;
case 2:
consultas.consultasn();
break;
}
}while(opc!=3);
break;
case 4:
bajas.mebajas();
break;
case 5:
            modifica.modificar();
break;
         case 6:
JOptionPane.showMessageDialog(null, "FIN del programa");
break;
default:
JOptionPane.showMessageDialog(null, "Opcion invalida");

}while(opcion!=6);
}  */ 
}

Clase Main
Código: [Seleccionar]
import java.io.*;
import java.util.ArrayList;
import javax.swing.JOptionPane;

public class Main
{
   private File archivo = new File("archiyect.txt");
private ArrayList<Medicamentos> medicamentos = new ArrayList<>();
   public Main(ArrayList<Medicamentos> medicamentos)
{
this.medicamentos = medicamentos;
}

   public static void main(String args[])throws FileNotFoundException, IOException
{   
//Inicializamos implementacion, quien tiene el ArrayList de Medicamentos
Implementacion implementacion = new Implementacion();
//Inicializamos el objeto que contiene las funciones del programa
AltasListado al = new AltasListado(implementacion.medicamentos);//Recibe el ArrayList de Medicamentos.
      Modificacion modifica = new Modificacion(implementacion.medicamentos);
      Consultas consultas = new Consultas(implementacion.medicamentos);
      Bajas bajas = new Bajas(implementacion.medicamentos);
     
String opcions;
int opcion;
do{
opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Listado de productos\n 3.Consulta de productos\n 4.Bajas\n 5. Modificacion 6.SALIR\n");
//opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Consulta productos\n 3.Baja porductos\n 4.Modificacion de un producto\n 5.Listado de productos\n 6. Salir\n ");
opcion=Integer.parseInt (opcions);
switch(opcion)
{
case 1:
al.altas();
break;
case 2:
al.listado();
break;
case 3:
String opcionl;
int opc;
do{
opcionl=JOptionPane.showInputDialog ("Menu\n 1.Busqueda por clave\n 2.Busqueda por nombre\n 3.SALIR");
opc=Integer.parseInt(opcionl);
switch(opc){
case 1:
consultas.consultasc();
break;
case 2:
consultas.consultasn();
break;
}
}while(opc!=3);
break;
case 4:
bajas.mebajas();
break;
case 5:
            modifica.modificar();
break;
         case 6:
JOptionPane.showMessageDialog(null, "FIN del programa");
break;
default:
JOptionPane.showMessageDialog(null, "Opcion invalida");

}while(opcion!=6);
}
}

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
Hola.
Basta con que "relajes" la restricción del modificador de acceso del ArrayList en la clase Implementacion.

Ahora mismo está como private, la más restrictiva. A este nivel solo los métodos o clases declarados dentro de la clase Implementación (dentro de una clase, puedes crear otras clases... es lo que se llama "anidar clases" (Nested Classes)) pueden ver el ArrayList.
Por eso antes el método main() podía acceder a él. Pero ahora que lo has sacado a otra clase, ya no puede verlo. Ha quedado fuera de su alcance (scope).

Por norma habitual, y por la filosofía de "encapsulamiento", siempre se recomienda que los atributos sean private y controlar su acceso "al exterior" mediante getters y setters.
Esto es importante sobre todo cuando escribimos clases y programas que vamos a compartir con otros programadores, y no queremos que estos metan la pata accediendo a "a lo loco" a estos atributos, ya que no conocen los entresijos de nuestro código y pueden hacer un uso erróneo de estos atributos.

Pero, si es un código que escribimos para nosotros, y que sabemos lo que nos hacemos y tal... podemos relajar el control de acceso a los atributos si esto nos ayuda a hacer más fácil el código.
De nuevo, la norma dice que debemos ir aumentando el nivel escalonadamente, de más restrictivo a menos, hasta que encontremos el nivel que necesitemos sin "abrir las puertas" del todo.

Hay cuatro niveles de acceso:
Código: [Seleccionar]
private ArrayList<Medicamentos> medicamentos = new ArrayList<>();private ya lo conocemos. El atributo solo es visible dentro de su propia clase.
Este ahora mismo no te sirve. Puedes salvarlo haciendo un getter que devuelva el ArrayList de Medicamentos.
O si no, pasar al siguiente nivel:

Código: [Seleccionar]
ArrayList<Medicamentos> medicamentos = new ArrayList<>();El siguiente nivel, es no poner ningún modificador de acceso. Así de simple.
A este nivel se le llama default y hace que el atributo sea visible a todas las clases que pertenezcan al mismo paquete (package)
Con este nivel ya te serviría para tu proposito. Tu nueva clase Main, al estar en el mismo paquete que Implementacion, podría acceder al ArrayList sin problemas.

Código: [Seleccionar]
protected ArrayList<Medicamentos> medicamentos = new ArrayList<>();El siguiente escalón es protected. Aquí le abrimos la puerta de acceso a clases de otros paquetes, pero solo si son subclases (es decir, que heredan) de Implementacion.

Esto significa que una clase de otro package declarada como:
Código: [Seleccionar]
class nuevaClase extends ImplementacionSí podría acceder al ArrayList, porque es una subclase. De lo contrario, no podría.

Código: [Seleccionar]
public ArrayList<Medicamentos> medicamentos = new ArrayList<>();Este es último nivel. Con public  abrimos la puerta para que cualquier clase, de cualquier paquete, pueda acceder al ArrayList y hacer con él lo quiera.

Esto significa que cualquier programador al que le pases tu clase Implementacion,podrá instanciar un objeto de esta clase y acceder libremente al ArrayList de Medicamentos, tal vez sin saber a ciencia cierta si es un ArrayList, o sin saber que tipo de datos puede albergar, o sin saber cuál es su propósito dentro del programa ni que importancia tiene.
Y si esto fuese un programa profesional, del mundo real, este ArrayList sería muy importante porque básicamente es una base de datos donde se estaría guardando todo el stock de productos de una empresa farmaceutica.
Así que si este programador es un poco osado o torpe, y piensa que en un momento dado se le puede poner valor null a ese atributo llamado medicamentos que no sabe muy bien lo que es (muy torpe hay que ser, pero los hay...) pues podría hacer perder una información valiosísima para la empresa.

Por esto debemos ser muy cuidadosos a la hora de declarar como public un atributo, porque lo estamos dejando "indefenso" ante otros programadores que no conocen a fondo nuestra clase.

En cambio, poniéndolo como private y usando getters y setters para establecer unas normas de seguridad de como debe usarse este atributo, evitamos errores y hacemos que nuestra clase sea sólida y fiable.
Por ejemplo (en plan humor):
Código: [Seleccionar]
if (nuevoArrayRecibido == null)
    mostrarMensajeAlerta("Pero cómo se te ocurre pasarme un null, cerebro de melón..");
else
{
    medicamentos = nuevoArrayRecibido;
    mostrarMensajeInformativo("Nuevo Array aceptado. Datos farmaceutica actualizados");
}

Bueno, y tras estas explicaciones (puedes ver más en un capitulo del curso de Aprender A Programar, volvamos a tu programa.

En Implementacion, basta con que elimines el modificador de acceso private al ArrayList de Medicamentos y no pongas nada. Así estaría en default, suficiente para que la clase Main tenga acceso a este array.

Luego en la clase Main, en realidad no necesitas declarar ningún atributo, ni tampoco usar ningún constructor.
Lo único importante es que lo primero que haga el programa sea instanciar la clase Implementacion que es por así decirlo, el "director de la orquesta" y el resto de clases dependen de ella.
Y así es como lo tienes, por tanto, basta con que elimines los atributos y el constructor, porque no los necesitas.
Ahora Main ya puede ver el ArrayList de Medicamentos y puede encargarse de pasárselo al resto de clases.

Pongo en comentario, lo que puedes quitar (atributos y constructor).
Clase Main
Código: [Seleccionar]
package farmaceutica;

import java.io.*;
import java.util.ArrayList;
import javax.swing.JOptionPane;

public class Main
{
//private File archivo = new File("archiyect.txt");
//private ArrayList<Medicamentos> medicamentos = new ArrayList<>();
/*
public Main(ArrayList<Medicamentos> medicamentos)
{
this.medicamentos = medicamentos;
}*/

public static void main(String args[])throws FileNotFoundException, IOException
{   
//Inicializamos implementacion, quien tiene el ArrayList de Medicamentos
Implementacion implementacion = new Implementacion();
//Inicializamos el objeto que contiene las funciones del programa
AltasListado al = new AltasListado(implementacion.medicamentos);//Recibe el ArrayList de Medicamentos.
Modificacion modifica = new Modificacion(implementacion.medicamentos);
Consultas consultas = new Consultas(implementacion.medicamentos);
Bajas bajas = new Bajas(implementacion.medicamentos);

String opcions;
int opcion;
do{
opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Listado de productos\n 3.Consulta de productos\n 4.Bajas\n 5. Modificacion 6.SALIR\n");
//opcions = JOptionPane.showInputDialog ("Menu\n 1.Altas productos\n 2.Consulta productos\n 3.Baja porductos\n 4.Modificacion de un producto\n 5.Listado de productos\n 6. Salir\n ");
opcion=Integer.parseInt (opcions);
switch(opcion)
{
case 1:
al.altas();
break;
case 2:
al.listado();
break;
case 3:
String opcionl;
int opc;
do{
opcionl=JOptionPane.showInputDialog ("Menu\n 1.Busqueda por clave\n 2.Busqueda por nombre\n 3.SALIR");
opc=Integer.parseInt(opcionl);
switch(opc){
case 1:
consultas.consultasc();
break;
case 2:
consultas.consultasn();
break;
}
}while(opc!=3);
break;
case 4:
bajas.mebajas();
break;
case 5:
modifica.modificar();
break;
case 6:
JOptionPane.showMessageDialog(null, "FIN del programa");
break;
default:
JOptionPane.showMessageDialog(null, "Opcion invalida");

}while(opcion!=6);
}
}

Creo que con esto ya debería funcionar. Ya nos contarás.
Un saludo.
« Última modificación: 17 de Junio 2018, 01:26 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

 

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