Un portátil con una bombilla y diversos engranajes alrededor.

🧑‍💻 App en Java con Swing que guarda alumnos en CSV


¿Estás empezando a programar en Java y te gustaría crear una app real con botones, formularios y archivos? 🚀
¡Estás en el sitio correcto! Hoy te enseño cómo hacer una app gráfica con Swing para gestionar alumnos. Podrás añadir, editar, eliminar y guardar en un archivo .csv. Quedará algo como esto que ves:

Formulario con los campos de un alumno y botones para las distintas acciones.

👉 Ideal para estudiantes de Bachillerato o CFGS DAM, usando Java 1.8.


🧠 ¿Qué aprenderás con este proyecto?

  • Crear ventanas con Swing
  • Usar eventos de botones
  • Leer y escribir en archivos .csv
  • Validar datos con expresiones regulares
  • Trabajar con listas de objetos (ArrayList)

🗂️ Paso 1: Crea la clase Alumno

Primero necesitamos un objeto que represente a cada alumno.

public class Alumno {
    private String nombre;
    private String correo;
    private byte edad;

    public Alumno(String nombre, String correo, byte edad) {
        this.nombre = nombre;
        this.correo = correo;
        this.edad = edad;
    }

    public String getNombre() { return nombre; }
    public void setNombre(String nombre) { this.nombre = nombre; }

    public String getCorreo() { return correo; }
    public void setCorreo(String correo) { this.correo = correo; }

    public byte getEdad() { return edad; }
    public void setEdad(byte edad) { this.edad = edad; }

    public String toCSV() {
        return nombre + "," + correo + "," + edad;
    }

    public static Alumno fromCSV(String linea) {
        String[] partes = linea.split(",");
        return new Alumno(partes[0], partes[1], Byte.parseByte(partes[2]));
    }
}


🎨 Paso 2: La ventana Swing frmAlumno

Esta es la interfaz que verás: con botones para navegar y campos para escribir nombre, correo y edad.

public class frmAlumno extends JFrame {
    // Componentes visuales
    private JLabel lbEstado;
    private JButton btnNuevo, btnBorrar, btnGuardar, btnCargar, btnSiguiente, btnAnterior, btnValidar;
    private JTextField txtNombre, txtCorreo, txtEdad;
    private int alumnoActual;
    List<Alumno> alumnos;

    public frmAlumno() {
        super("Gestión de Alumnos");
        alumnos = new ArrayList<>();
        alumnoActual = -1;
        initComponents();
        actualizar();
    }


🎨 Paso 3: Construir la interfaz gráfica con Swing (explicado paso a paso)

En este paso vamos a definir visualmente cómo se verá nuestra aplicación: dónde colocamos los botones, campos de texto, etiquetas, etc. Lo haremos dentro del método initComponents().


🧱 1. Estructura base de la ventana

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());

  • setDefaultCloseOperation(...): Hace que la aplicación se cierre correctamente al pulsar la «X».
  • getContentPane().setLayout(new BorderLayout()): Divide la ventana en 5 zonas: NORTE, SUR, ESTE, OESTE y CENTRO. Esto nos da mucha flexibilidad para organizar los elementos.

📍 2. Zona SUR: Estado de alumnos

JPanel pEstado = new JPanel();
pEstado.setLayout(new GridLayout());
lbEstado = new JLabel("Alumno 0 de 0");
pEstado.add(lbEstado);
lbEstado.setHorizontalAlignment(JLabel.CENTER);
getContentPane().add(pEstado, BorderLayout.SOUTH);

  • Creamos un panel pEstado.
  • Dentro colocamos una etiqueta lbEstado para mostrar cuántos alumnos hay y en cuál estamos.
  • Lo colocamos en el SUR de la ventana.

🔎 Ejemplo visible: “Alumno 3 de 5”


🖱️ 3. Zona NORTE: Botones con iconos

JPanel pIconos = new JPanel();
pIconos.setLayout(new GridLayout());
getContentPane().add(pIconos, BorderLayout.NORTH);

Este panel va en la parte superior. Le añadiremos botones con imágenes (.png) para:

  • 🆕 Nuevo
  • Borrar
  • 💾 Guardar
  • 📂 Cargar
File f = new File("." + File.separator + "src");
String path = f.getAbsolutePath() + File.separator;

btnNuevo = new JButton(new ImageIcon(path + "nuevo.png"));
btnNuevo.addActionListener(e -> nuevo());
pIconos.add(btnNuevo);

Repetimos lo mismo para btnBorrar, btnGuardar y btnCargar.

Consejo: Las imágenes deben estar en /src con nombres exactos: nuevo.png, guardar.png, etc.


🧍‍♂️ 4. Zona CENTRAL: Formulario del alumno

Ahora construimos la parte principal con el formulario.

JPanel pCentral = new JPanel();
getContentPane().add(pCentral, BorderLayout.CENTER);
pCentral.setLayout(new BorderLayout());

Creamos otro panel pAlumno dentro del pCentral:

JPanel pAlumno = new JPanel();
pAlumno.setLayout(new BorderLayout());
pCentral.add(pAlumno, BorderLayout.CENTER);


📌 5. Subzona SUR del formulario: Navegación y validación

JPanel pNavegacion = new JPanel();
pAlumno.add(pNavegacion, BorderLayout.SOUTH);
pNavegacion.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();

Colocamos 3 botones:

  • < para Anterior
  • Validar los datos
  • > para Siguiente
gbc.gridx = 0;
btnAnterior = new JButton("<");
btnAnterior.addActionListener(e -> anterior());
pNavegacion.add(btnAnterior, gbc);

gbc.gridx = 1;
btnValidar = new JButton("Validar");
btnValidar.addActionListener(e -> editar());
pNavegacion.add(btnValidar, gbc);

gbc.gridx = 2;
btnSiguiente = new JButton(">");
btnSiguiente.addActionListener(e -> siguiente());
pNavegacion.add(btnSiguiente, gbc);

🧠 Usamos GridBagLayout, que permite organizar elementos con gran precisión.


✏️ 6. Subzona CENTRAL del formulario: Campos de datos

Aquí colocamos las etiquetas y los campos de texto para nombre, correo y edad.

JPanel pDatos = new JPanel();
pAlumno.add(pDatos, BorderLayout.CENTER);
pDatos.setLayout(new GridBagLayout());

Cada etiqueta + campo se organiza en una fila:

gbc.gridx = 0;
gbc.gridy = 0;
JLabel label = new JLabel("Nombre: ");
label.setHorizontalAlignment(SwingConstants.RIGHT);
pDatos.add(label, gbc);

gbc.gridx = 1;
txtNombre = new JTextField(10);
pDatos.add(txtNombre, gbc);

Repetimos esto mismo para Correo y Edad, cambiando gbc.gridy a 1 y 2 respectivamente.


🧷 7. Finalización: Ajustar y mostrar

pack(); // Ajusta automáticamente el tamaño de la ventana
setLocationRelativeTo(null); // Centra la ventana en la pantalla
setVisible(true); // Muestra la ventana


💾 Paso 4: Guardar y cargar en CSV

Aquí usamos BufferedWriter y BufferedReader para trabajar con archivos de texto .csv.

private void guardar() {
    try (BufferedWriter bw = Files.newBufferedWriter(Paths.get("alumnos.csv"))) {
        for (Alumno alumno : alumnos) {
            bw.write(alumno.toCSV());
            bw.newLine();
        }
    } catch (IOException e) {
        System.err.println("Error al guardar el archivo...");
    }
}

private void cargar() {
    try (BufferedReader br = Files.newBufferedReader(Paths.get("alumnos.csv"))) {
        String linea;
        alumnos.clear();
        alumnoActual = -1;
        while ((linea = br.readLine()) != null) {
            alumnos.add(Alumno.fromCSV(linea));
            alumnoActual++;
        }
        actualizar();
    } catch (IOException e) {
        System.err.println("Error al cargar datos.");
    }
}


✅ Paso 5: Validar entradas

Es muy importante que el usuario no meta datos incorrectos. ¡Validamos con expresiones regulares!

private void editar() {
    if (!txtNombre.getText().trim().matches("([a-zA-Z]+\\s?)+")
        || !txtCorreo.getText().trim().matches("([a-z][a-z0-9_.]*)@([a-z][a-z0-9_.]*)[.]([a-z]){2,5}")
        || !txtEdad.getText().matches("[1-9][0-9]?")) {

        String mensaje = String.format("<html><body>%s<br>%s<br>%s<br></body></html>",
                "Nombre correcto: <font color='red'>" + txtNombre.getText().trim().matches("([a-zA-Z]+\\s?)+") + "</font>",
                "Correo correcto: " + txtCorreo.getText().trim().matches("([a-z][a-z0-9_.]*)@([a-z][a-z0-9_.]*)[.]([a-z]){2,5}"),
                "Edad correcta: " + txtEdad.getText().matches("[1-9][0-9]?")
        );
        JOptionPane.showMessageDialog(this, mensaje, "Validación", JOptionPane.WARNING_MESSAGE);
    } else {
        Alumno alumno = alumnos.get(alumnoActual);
        alumno.setCorreo(txtCorreo.getText());
        alumno.setEdad(Byte.parseByte(txtEdad.getText()));
        alumno.setNombre(txtNombre.getText());
    }
}


🚀 Paso 6: Lógica de navegación

Puedes ver diferentes alumnos con los botones de navegación:

private void siguiente() {
    alumnoActual++;
    actualizar();
}

private void anterior() {
    alumnoActual--;
    actualizar();
}

private void nuevo() {
    alumnos.add(new Alumno("Nombre", "cambiacorreo@ya.now", (byte) 1));
    alumnoActual = alumnos.size() - 1;
    actualizar();
}


🧠 Bonus: Método actualizar()

Este método actualiza el formulario según el alumno seleccionado.

private void actualizar() {
    btnAnterior.setEnabled(alumnoActual != 0 && alumnoActual != -1);
    btnSiguiente.setEnabled(alumnoActual < alumnos.size() - 1 && alumnoActual != -1);
    btnValidar.setEnabled(alumnoActual != -1);

    if (alumnoActual == -1) {
        txtCorreo.setText("");
        txtEdad.setText("");
        txtNombre.setText("");
    } else {
        Alumno a = alumnos.get(alumnoActual);
        txtNombre.setText(a.getNombre());
        txtCorreo.setText(a.getCorreo());
        txtEdad.setText(String.valueOf(a.getEdad()));
    }

    lbEstado.setText("Alumno " + (alumnoActual + 1) + " de " + alumnos.size());
}


🧪 ¿Cómo ejecuto el programa?

Crea una clase con main:

public class Main {
    public static void main(String[] args) {
        new frmAlumno();
    }
}

Compila y ejecuta en IntelliJ, NetBeans, Eclipse o desde línea de comandos.


🔚 Conclusión

¡Y listo! Has creado tu propia mini aplicación de gestión de alumnos en Java con interfaz gráfica, lectura y escritura de archivos CSV, y validación de datos. ¡Un proyecto de nivel profesional hecho paso a paso!


Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.