import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.JOptionPane; import javax.swing.JFileChooser; import java.io.*; /** * Clase de practica para el manejo de archivos binarios en Java. * * @author Magus * @version 1.0 */ public class Agenda extends JFrame implements ActionListener { private JCheckBox chkCasado; private JLabel lblNombre; private JLabel lblEdad; private JLabel lblPeso; private JTextField txtEdad; private JTextField txtNombre; private JTextField txtPeso; private JButton btnPrev; private JButton btnNext; private JLabel lblIndex; /** * Vamos a manejar el archivo mediante dos variables, una de indice que nos * indica cual de los registros vamos a leer y otra que guarda el total de * registros. Esta manera de utilizar archivos no es muy eficiente, pero es * una de las maneras más sencillas de utilizar un solo archivo para guardar * una gran cantidad de objetos. */ private int index = 0; private int total = 0; /** Nos dice si el archivo esta en modo de edicion */ private boolean edit = true; /** * Es el archivo abierto, nos permite leer y guardar de cualquier lugar de * la aplicacion */ private File openFile = null; private DataInputStream fileIn; private DataOutputStream fileOut; /** * Metodo que inicia la clase. Crea la interfaz y despues abre el archivo * para iniciar las variables necesarias. */ public Agenda() { GridBagConstraints gridBagConstraints; lblNombre = new JLabel(); txtNombre = new JTextField(); lblEdad = new JLabel(); txtEdad = new JTextField(); chkCasado = new JCheckBox(); lblPeso = new JLabel(); txtPeso = new JTextField(); btnPrev = new JButton(); btnNext = new JButton(); lblIndex = new JLabel(); getContentPane().setLayout(new GridBagLayout()); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); lblNombre.setLabelFor(txtNombre); lblNombre.setText("Nombre"); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; getContentPane().add(lblNombre, gridBagConstraints); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 0; gridBagConstraints.gridwidth = 3; gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.weightx = 3.0; gridBagConstraints.weighty = 1.0; getContentPane().add(txtNombre, gridBagConstraints); lblEdad.setText("Edad"); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; getContentPane().add(lblEdad, gridBagConstraints); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 1; gridBagConstraints.gridwidth = 3; gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.weightx = 3.0; gridBagConstraints.weighty = 1.0; getContentPane().add(txtEdad, gridBagConstraints); chkCasado.setText("\u00bfCasado?"); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 3; gridBagConstraints.gridwidth = 4; gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; getContentPane().add(chkCasado, gridBagConstraints); lblPeso.setText("Peso"); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; getContentPane().add(lblPeso, gridBagConstraints); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 2; gridBagConstraints.gridwidth = 3; gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.weightx = 3.0; gridBagConstraints.weighty = 1.0; getContentPane().add(txtPeso, gridBagConstraints); btnPrev.setText("<"); btnPrev.addActionListener(this); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridy = 4; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; getContentPane().add(btnPrev, gridBagConstraints); btnNext.setText(">"); btnNext.addActionListener(this); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridy = 4; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; getContentPane().add(btnNext, gridBagConstraints); gridBagConstraints.gridy = 5; gridBagConstraints.gridwidth = GridBagConstraints.REMAINDER; gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; getContentPane().add(lblIndex, gridBagConstraints); /** * Creo un JFileChooser para mostrar un dialogo de seleccion de archivos */ JFileChooser fc = new JFileChooser(); fc.setDialogTitle("Elige el archivo para abrir"); fc.setFileSelectionMode(JFileChooser.FILES_ONLY); int ret = fc.showOpenDialog(null); if (ret == JFileChooser.APPROVE_OPTION) { try { openFile = fc.getSelectedFile(); fileOut = new DataOutputStream(new FileOutputStream(openFile, true)); fileIn = new DataInputStream(new FileInputStream(openFile)); Persona p = new Persona(); /** Leo todos los registros para saber cuantos hay en total */ while (true) { p.readObject(fileIn); edit = false; total++; } } catch (EOFException eofe) { /** * Esta excepcion se dispara cuando se termina el archivo */ try { /** Cierro los dos streams */ fileOut.close(); fileIn.close(); } catch (IOException ioe) { } } catch (IOException ioe) { JOptionPane.showMessageDialog(null, "No puedo leer el archivo!", "Error", JOptionPane.ERROR_MESSAGE); System.exit(1); } catch (ClassNotFoundException cnfe) { JOptionPane.showMessageDialog(null, "No encuentro la clase. \nEs posible que este error " + "se deba a que tienes un programa incompleto", "Error", JOptionPane.ERROR_MESSAGE); } } else { JOptionPane.showMessageDialog(null, "No puedo trabajar sin un archivo de agenda!", "Error", JOptionPane.ERROR_MESSAGE); System.exit(1); } lblIndex.setText("Hoja " + (index + 1) + " de " + total); setSize(300,500); setTitle("Manejo de Archivos"); setVisible(true); } /** * @param args argumentos de la lina de comandos */ public static void main(String[] args) { Agenda app = new Agenda(); } /** * Metodo que responde a eventos, se va a encargar de manejar los archivos. * En caso de que el boton presionado fuera el boton de abrir abre el archivo * que se ha puesto en la linea de archivo, en caso de que el boton presionado * fuera el de guardar guarda los datos de la forma al archivo en la linea * de nombre de archivo. * * @param e Evento que sucedio. */ public void actionPerformed(ActionEvent e) { /** Si estoy editando uno nuevo */ if (edit) { savePersona(); /** Le sumo uno al total y ya no estoy editando */ total++; edit = false; } if (e.getSource() == btnNext) { /** * Si hicieron click en el boton siguiente le sumo uno a indice * para mostrar el siguiente, si el indice es menor que el total lo * muestro, si es mayor que el total preparo la forma para guardar * un nuevo registro con el metodo makePersona() */ index++; if (index < total) readPersona(index); else makePersona(); } else if (e.getSource() == btnPrev) { /** * Si hicieron click ene l boton anterior lengthresto uno a indice * para mostrar el anterior. */ if (index > 0) index--; readPersona(index); } lblIndex.setText("Hoja " + (index + 1) + " de " + total); } /** * Metodo que lee la persona que se encuentre en la posicion pasada como * parametro. La posicion tiene que ser un entero positivo mayor o igual a * cero. * * @param index Indica la posicion que se va a leer del archivo. */ public void readPersona(int index) { Persona p = new Persona(); try { fileIn = new DataInputStream(new FileInputStream(openFile)); /** * Leo n registros para posicionarme en el registro que tengo que * devolver * * Si el archivo es una lista * 0 ------ * 1 ------ <- Este es el registro que busco * 2 ------ * Por lo tanto tengo que leer la primera linea aunque no la utilice * para nada para posicionarme en la segunda */ for (int i = 0; i < index; i++) { p.readObject(fileIn); } /** * Leo la siguiente linea y copio todo a las cajas de texto */ p.readObject(fileIn); txtNombre.setText(p.getNombre()); txtEdad.setText(String.valueOf(p.getEdad())); txtPeso.setText(String.valueOf(p.getPeso())); chkCasado.setSelected(p.isCasada()); } catch (FileNotFoundException fnfe) { JOptionPane.showMessageDialog(null, "No encuentro el archivo!", "Error", JOptionPane.ERROR_MESSAGE); } catch (IOException ioe) { JOptionPane.showMessageDialog(null, "No puedo leer el archivo!", "Error", JOptionPane.ERROR_MESSAGE); } catch (ClassNotFoundException cnfe) { JOptionPane.showMessageDialog(null, "No encuentro la clase. \nEs posible que este error " + "se deba a que tienes un programa incompleto", "Error", JOptionPane.ERROR_MESSAGE); } } /** * Metodo que guarda una persona al final del archivo con los datos que se * encuentren en las cajas de texto */ public void savePersona() { /** Preparo los datos... */ String nombre = txtNombre.getText(); int edad = 0; if ( !txtEdad.getText().equals("") ) edad = Integer.parseInt(txtEdad.getText()); double peso = 0.0; if ( !txtPeso.getText().equals("") ) peso = Double.parseDouble(txtPeso.getText()); boolean isCasada = chkCasado.isSelected(); /** ...para crear la persona a guardar */ Persona p = new Persona(nombre, edad, peso, isCasada); try { /** * El segundo parametro en el FileOutputStream significa append, es * decir que lo que escriba lo va a poner al final del archivo y no * va a borrar lo que ya estaba escrito. */ fileOut = new DataOutputStream(new FileOutputStream(openFile, true)); p.writeObject(fileOut); } catch (FileNotFoundException fnfe) { JOptionPane.showMessageDialog(null, "No encuentro el archivo!", "Error", JOptionPane.ERROR_MESSAGE); } catch (IOException ioe) { JOptionPane.showMessageDialog(null, "No puedo leer el archivo!", "Error", JOptionPane.ERROR_MESSAGE); } } /** * Metodo que borra los campos de la forma y pone a la aplicacion en el modo * de edicion */ public void makePersona() { /** * Pongo todos los campos en blanco y cambio la variable edit a * verdadero para mostrar que estoy editando una persona */ txtNombre.setText(""); txtEdad.setText(""); txtPeso.setText(""); chkCasado.setSelected(false); edit = true; } }