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

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
ARTÍCULO ANTERIOR

SIGUIENTE ARTÍCULO

¡SÉ EL PRIMERO EN COMENTAR!
Conéctate o Regístrate para dejar tu comentario.