New 2 Java: Construir una Aplicación: 5.- Escribir Objetos a Ficheros, Usar Arrays y más...

El m�todo getText devuelve un String para un objeto.
�Qu� m�todo se puede utilizar para borrar de los campos de texto y las etiquetas los strings que contienen?

El m�todo setText funciona bien para limpiar los campos de texto, si inclu�mos un string vac�o. Por ejemplo, el siguiente c�digo configura un campo de texto para no mostrar nada:

name.setText("");

El campo de texto est� listo para una nueva entrada.

.�Limpiar y Configurar la Entrada en el GUI

Podemos f�cilmente limpiar los campos de texto llamando al m�todo setText de cada componente GUI. Suministrando "" como un string vac�o, o poniendo un valor 0 si es necesario.

Sigue estos pasos...
  1. Abre el fichero UIWestPanel.java en tu editor de texto.
  2. A�ade el siguiente m�todo clearFields:
    public void clearFields()
      {
        shoreButton.setSelected(true);
        date.setText("00/00/00");
        psiStart.setText("0000"); 
        psiEnd.setText("000");
        psiUsed.setText("");
        bottomTime.setText("00"); 
        vis.setText("00");
        comments.setText("");
      }
    
  3. Graba el fichero.

La clase DiveHandler llama al m�todo clearFields despu�s de llamar a los m�todos que escriben el objeto en un fichero.

Luego, el GUI tiene un bot�n View que lee el objeto y pone sus valores en los campos. Definimos este m�todo setFields en la clase UIWestPanel donde se crearon los componentes GUI, pero la clase que maneja la funcionalidad (DiveHandler) llama al m�todo donde sea apropiado.

Sigue estos pasos...
  1. Abre el fichero UIWestPanel.java en tu editor de texto.
  2. Define el m�todo setFields:
    public void setFields(String string[])
      throws IllegalArgumentException
         {
           if (string.length <= 0)
            throw new IllegalArgumentException(
            "Not enough fields were filled in");
    
            //Checks to see which bottom 
            //was selected.
     
            date.setText(string[0]);
            maxDepths.setSelectedItem(string[1]);
            //rb.setSelectedItem(string[2]);
            psiStart.setText(string[3]);
            psiEnd.setText(string[4]);
            psiUsed.setText(string[5]);
            bottomTime.setText(string[6]);
            diveNumberL.setText(string[7]);
            vis.setText(string[8]);
            comments.setText(string[9]);
          }
    
  3. Graba el fichero.

Tu clase deber�a parecerse a UIWestPanel.java.

Ya hemos inicializado todos los componentes GUI dentro de la clase UIWestPanel. Adem�s, la clase proporciona los m�todos que otras clases pueden llamar para recoger y trabajar con los datos. Esto har� m�s facil realizar cambios posteriormente, si decidimos a�adir un bot�n u otro campo de texto, o si queremos cambiar el texto de una etiqueta, sabremos exactamente con qu� clases trabajar. Si decidimos que necesitamos m�s funcionalidad, sabemos que tenemos que editar la clase DiveHandler, que maneja los eventos del panel Log Dives. En otras palabras, la arquitectura MVC nos ofrece una forma l�mpia de organizar nuestro c�digo para que podamos planear una aplicaci�n y hacer los cambios m�s tarde.

.�La Clase Controladora

Ahora que hemos dise�ado los componentes GUI, y con las clases que definen un objeto Dive en su lugar, necesitamos crear una clase que inicialice las clases UIWestPanel y DiveRecord, y proporcionar la funcionalidad para los botones Save y View. En otras palabras, esta nueva clase controla qu� objetos se inicializan, c�mo se llama a los m�todos para trabajar con los datos, y qu� sucede en el manejo de eventos. Esta clase es el controlador.

Al igual que las otras clases, DiveHandler est� en el paquete divelog. Adem�s, necesita importar los siguientes paquetes:

  • java.awt and javax.swing para crear botones
  • java.awt.event para el manejo de eventos
  • java.io para leer y escribir objetos
  • java.util.Vector para almacenar datos

Como clase controladora, DiveHandler inicializa UIWestPanel y DiveRecord, por eso necesitamos crear una referencia a estas clases. Adem�s, creamos unos objetos de entrada y salida para leer y escrbir objetos DiveRecord en un fichero. Para hacer esto, usamos las clases ObjectOutputStream y ObjectInputStream.

Sigue estos pasos...
  1. Crea un fichero Llamado DiveHandler.java en tu editor de texto.
  2. Declara lo siguiente:
      private UIWestPanel ui;
      private DiveRecord Dr;
      private JButton enterButton; 
      private JButton viewButton;
      private int callIndex;
      //To check if the file has been opened already
      private boolean calledAlready = false;
      //To hold dive objects
      private Vector _cacheList = new Vector();  
      private ObjectOutputStream output;
      private ObjectInputStream input;
    
  3. Graba el fichero.

La variable booleana calledAlready se utiliza m�s adelante para ver si se ha abierto el fichero antes de leer o escribir, y el objeto Vector se utiliza para almacenar cada objeto DiveRecord que se escribe. Entonces se utiliza la variable callIndex para seguir la pista de cu�ntos objetos se han escrito en el fichero. Por �ltimo, se declaran las variables para los streams de entrada y salida.

.�Leer y Escribir Objetos Serializados

Anteriormente en esta lecci�n, aprendimos c�mo serializar objetos y de esta forma hacerlos persistentes en memoria escribiendo el estado del objeto en un stream. El prop�sito principal de la serializaci�n es escribir los valores de las variables de ejemplar de un objeto. Los objetos pueden almacenar su propio estado en un fichero y luego restaurarlo posteriormente. Ya hemos preparado la clase DiveRecord para su serializaci�n implementando el interface Serializable. Este interface no tiene ning�n m�todo que tengamos que implementar en nuestra clase. Simplemente le dice al compilador que la clase DiveRecord participa del protocolo serializable.

Otra forma de escribir objetos a ficheros es usar las clases ObjectInputStream y ObjectOutputStream del paquete java.io. ObjectInputStream se asegura de que los tipos de todos los objetos creados desde el stream corresponden con clases que est�n presentes en la M�quina Virtual Java. Las clases se cargan cuando es necesario usando los mecanismos est�ndard.

.�ObjectInputStream

Un objeto ObjectInputStream puede leer tipos de datos primitivos y representaciones de objetos, y puede deserializar datos primitivos y objetos escritos pr�viamente usando un objeto ObjectOutputStream.

Envolvemos un objeto ObjectOutputStream alrededor de un objeto InputStream para darle al objeto InputStream subyacente esta funcionalidad:

FileInputStream fis = new FileInputStream("FiletobeRead.txt");
ObjectInputStream ois = new ObjectInputStream(fis);

Con este c�digo, se crea un objeto FileInputStream envuelto en el ObjectInputStream.

Leer un objeto es similar a ejecutar los constructores de un nuevo objeto. Se asigna la memoria para el objeto y se inicializa a zero (NULL). Se llama a los constructores sin argumentos de las clases no-serializables, y se restauran los campos de las clases serializables desde el stream empezando con la clase serializable m�s cercana a java.lang.object y terminando con la clase m�s espec�fica.

El m�todo readObject se utiliza para leer un objeto desde el stream:

String file = (String) ois.readObject();

.�ObjectOutputStream

Un ObjectOutputStream escribe tipos de datos primitivos y representaciones de objetos en un OutputStream. S�lo se pueden escribir en los streams los objetos que soporten el interface java.io.Serializable. La clase de cada objeto serializable se codifica, incluyendo el nombre y la firma de la clase, los valores de los campos y arrays del objeto, y la representaci�n de cualquier otro objeto referenciado por el objeto inicial.

Usamos el m�todo writeObject para escribir un objeto en el stream. Cualquier objeto, incluyendo strings y arrays, se escribe con writeObject. El objeto se debe leer desde el correspondiente ObjectInputstream con los mismos tipos y en el mismo orden en que fueron escritos.:

FileOutputStream fos = new FileOutputStream("t.tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeInt(12345);
oos.writeObject("Today");
oos.writeObject(new Date());
oos.close();

El m�todo writeObject es responsable de escribir el estado del objeto para su clase particular para que el correspondiente m�todo readObject pueda restaurarlo.

Sigue estos pasos...
  1. Abre el fichero DiveHandler.java en tu editor de texto.
  2. Empieza el constructor de esta forma:
      public DiveHandler()
       {//Opens constructor
        //Initialize and add graphic user interface
         ui = new UIWestPanel();
         add("Center",ui);
       try
         { //open try 
        output = new ObjectOutputStream (
                          new FileOutputStream ("diveLogs.dat", true));
         } catch (IOException ioex)
        {//open catch
                      JOptionPane.showMessageDialog(null,
                      "Error during reading file",
                      null, JOptionPane.ERROR_MESSAGE);
         }//close catch 
         try{       
          input = new ObjectInputStream(
                          new FileInputStream("diveLogs.dat"));
                          }
          catch (IOException ioex)
         {//open catch
                      JOptionPane.showMessageDialog(null,
                      "Error during reading file",
                      null, JOptionPane.ERROR_MESSAGE);
         }//close catch
    
  3. Graba el fichero.

Observa que en el c�digo de arriba, tambi�n hemos tenido que proporcionar el manejo de excepciones. Si ocurre alg�n problema, se podr�a lanzar una IOException. Para que el usuario conozca el problema, se proporcionan objetos JOptionPane con mensajes de texto.

Una vez establecidos los streams de entrada y salida, proporcionamos la funcionalidad de los botones de esta clase controladora. Recuerda que en la clase UIWestPanel, proporcionamos un m�todo get para cada bot�n. Llamando al m�todo get, creamos un ejemplar de los botones en la clase controladora. Una vez que tenemos un ejemplar del bot�n con un identificador asignado, podemos hacer lo siguiente:

  • Asignar el texto a mostrar en los botones.
  • Registrar los botones con un oyente.
  • Proporcionar las instrucciones para lo que queremos que suceda cuando se pulsa el bot�n en el m�todo oyente.

Ya creamos los identificadores para los botones en la parte superior de DiveHandler, e inicializamos un ejemplar de UIWestPanel para llamar a los m�todos get apropiados. Simplemente llamamos al m�todo y le asignamos el identificador del bot�n apropiado:

Sigue estos pasos...
  1. Abre el fichero DiveHandler.java en tu editor de texto.
  2. Asigna un ejemplar de uno de los botones de UIWestPanel al identificador enterButton en la clase controladora:
    enterButton = ui.getEnter();
    
  3. Muestra el texto del bot�n:
    enterButton.setText("Enter");
    
  4. Graba el fichero.

Haremos lo mismo con el otro bot�n m�s adelante. Ahora veremos como registar el bot�n con un oyente.

.�Clases Internas An�minas

En lecciones anteriores registramos objetos con oyentes e implementamos el interface en esa clase o en una clase completamente separada. Como DiveHandler es la clase controladora y queremos mantener la funcionalidad en esta clase, podemos:

  • Hacer que la clase DiveHandler implemente el interface listener. Como tenemos dos botones, primero tenemos que chequear qu� bot�n se ha pulsado, luego proporcionar las instrucciones en un m�todo actionPerformed para cada bot�n.
  • Usar clases an�nimas cuando registremos cada bot�n, haciendo el c�digo m�s conciso.

En la siguiente p�gina aprenderemos c�mo utilizar clases internas an�nimas.

�La siguiente sentencia es verdadera o falsa?
Las clase an�nimas internas se declaran y ejemplarizan al mismo tiempo,usando la palabra clave new con el nombre de la clase o el interface existentes.
  A   Verdadera
  B.   Falsa

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
ARTÍCULO ANTERIOR

SIGUIENTE ARTÍCULO