Diseñando Interfaces con Layouts en Swing

1. Introducción

En la sesión anterior, aprendimos a crear una ventana básica con Swing y agregar un botón. Sin embargo, para diseñar interfaces más complejas necesitamos organizar los componentes dentro de la ventana. En esta sesión, aprenderemos:

  • Cómo funcionan los Layouts en Swing para organizar los componentes.
  • Cómo añadir más componentes como etiquetas, campos de texto y botones.
  • Cómo manejar eventos de usuario de la forma más simple, con ActionListener.

Al final de esta sesión, serás capaz de crear una interfaz gráfica más avanzada y responder a las acciones del usuario. 🚀


2. ¿Qué es un Layout en Swing?

Un Layout es el gestor de disposición de los componentes en un contenedor (por ejemplo, una ventana JFrame o un panel JPanel). Swing ofrece varios gestores de diseño que nos permiten colocar los elementos de manera automática sin necesidad de definir coordenadas manualmente.

Tipos de Layouts más usados

  • FlowLayout – Organiza los elementos en fila, de izquierda a derecha.
  • BorderLayout – Divide la ventana en cinco zonas: Norte, Sur, Este, Oeste y Centro.
  • GridLayout – Organiza los elementos en una cuadrícula con filas y columnas.
  • BoxLayout – Permite organizar elementos en una sola fila o columna.
  • GridBagLayout – Es más avanzado y permite organizar los componentes como si los estuvieras maquetando en una tabla con columnas de ancho variable y filas de alto variable. Si sabes HTML, es algo parecido a lo que conseguimos con colspan y rowspan.

🎯 IMPORTANTE: Sin un Layout, los componentes pueden superponerse o no mostrarse correctamente en diferentes pantallas.

👀 Ten en cuenta que hay más Layouts, pero empiezan a ser más complejos para el nivel que pretendemos tener ahora mismo. Además, existen herramientas WYSIWYG en diversos IDE (Netbeans e IntelliJ son las que más me gustan) que facilitan el diseño a golpe de ratón.


3. Creando una Ventana con un Layout

Ejemplo 1: FlowLayout – Distribución en línea

FlowLayout es el más simple: coloca los elementos uno al lado del otro como si fueran texto en un documento.

import javax.swing.*;
import java.awt.*;

public class VentanaFlowLayout extends JFrame {
    public VentanaFlowLayout() {
        setTitle("Ejemplo FlowLayout");
        setSize(300, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new FlowLayout()); // Aplicamos FlowLayout

        add(new JButton("Botón 1"));
        add(new JButton("Botón 2"));
        add(new JButton("Botón 3"));

        setVisible(true);
    }

    public static void main(String[] args) {
        new VentanaFlowLayout();
    }
}

🔹 Explicación:

  • Se establece setLayout(new FlowLayout()); para usar FlowLayout.
  • Los botones se añaden en el orden en que se crean.
  • La ventana se ajusta automáticamente al tamaño de los componentes.

Ejemplo 2: BorderLayout – Dividir en zonas

BorderLayout nos permite organizar los elementos en cinco posiciones dentro de la ventana:

  • NORTH (Norte) – Parte superior
  • SOUTH (Sur) – Parte inferior
  • EAST (Este) – Lado derecho
  • WEST (Oeste) – Lado izquierdo
  • CENTER (Centro) – Área central
import javax.swing.*;
import java.awt.*;

public class VentanaBorderLayout extends JFrame {
    public VentanaBorderLayout() {
        setTitle("Ejemplo BorderLayout");
        setSize(400, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout()); // Aplicamos BorderLayout

        add(new JButton("Norte"), BorderLayout.NORTH);
        add(new JButton("Sur"), BorderLayout.SOUTH);
        add(new JButton("Este"), BorderLayout.EAST);
        add(new JButton("Oeste"), BorderLayout.WEST);
        add(new JButton("Centro"), BorderLayout.CENTER);

        setVisible(true);
    }

    public static void main(String[] args) {
        new VentanaBorderLayout();
    }
}

🔹 Explicación:

  • Se usa BorderLayout para distribuir los componentes en zonas.
  • Los botones se colocan en las posiciones indicadas (NORTH, SOUTH, EAST, etc.).
  • Si un componente está en CENTER, ocupa todo el espacio restante.

Ejemplo 3: GridLayout – filas y columnas

GridLayout organiza los componentes en filas y columnas de tamaño fijo. Es ideal para interfaces donde todos los elementos deben ocupar el mismo espacio, como teclados numéricos, tableros de juego o formularios sencillos.

📌 Características principales:

  • Se define con new GridLayout(filas, columnas).
  • Todos los elementos ocupan el mismo tamaño.
  • La cuadrícula se llena de izquierda a derecha y de arriba abajo.

Aquí tienes un ejemplo de una calculadora muy sencilla:

import javax.swing.*;
import java.awt.*;

public class CalculadoraGrid extends JFrame {
    public CalculadoraGrid() {
        setTitle("Calculadora GridLayout");
        setSize(300, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout()); // Usamos BorderLayout para organizar mejor

        // Campo de texto para los números
        JTextField pantalla = new JTextField();
        pantalla.setEditable(false); // Solo lectura
        add(pantalla, BorderLayout.NORTH); // Colocamos arriba

        // Panel para los botones
        JPanel panelBotones = new JPanel();
        panelBotones.setLayout(new GridLayout(4, 4, 5, 5)); // 4 filas, 4 columnas, separación 5px

        // Array con los textos de los botones
        String[] botones = {
            "7", "8", "9", "/",
            "4", "5", "6", "*",
            "1", "2", "3", "-",
            "0", "C", "=", "+"
        };

        // Añadir los botones al panel
        for (String texto : botones) {
            panelBotones.add(new JButton(texto));
        }

        add(panelBotones, BorderLayout.CENTER); // Colocamos el panel en el centro
        setVisible(true);
    }

    public static void main(String[] args) {
        new CalculadoraGrid();
    }
}

🔹 Explicación:

1️⃣ Creamos la ventana con JFrame y le damos un tamaño de 300x400.
2️⃣ Añadimos un JTextField arriba (BorderLayout.NORTH) para mostrar los números.
3️⃣ Creamos un JPanel con GridLayout(4, 4, 5, 5) con 4 filas y 4 columnas y un espaciado de 5 píxeles entre botones.
4️⃣ Añadimos los botones con un bucle, recorriendo el array de textos ("0", "1", "+", "=", etc.).
5️⃣ Mostramos la ventana con setVisible(true).

Resultado: Se obtiene una interfaz con botones organizados en una cuadrícula uniforme.

Ejemplo 4: GridBagLayout – mayor control

GridBagLayout es un gestor de diseño más flexible y avanzado que permite:

  • Definir tamaños diferentes para cada celda.
  • Hacer que los elementos se expandan según el tamaño de la ventana.
  • Ajustar alineación y separación de los elementos.

📌 Conceptos clave:

  • GridBagConstraints → Se usa para definir posición, tamaño y alineación de los componentes.
  • weightx y weighty → Controlan cómo los componentes crecen o se encogen.
  • gridx y gridy → Indican la posición en la cuadrícula.
import javax.swing.*;
import java.awt.*;

public class LoginGridBag extends JFrame {
    public LoginGridBag() {
        setTitle("Login con GridBagLayout");
        setSize(300, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new GridBagLayout()); // Usamos GridBagLayout

        GridBagConstraints gbc = new GridBagConstraints(); // Configuración de celdas

        // Etiqueta Usuario
        gbc.gridx = 0; gbc.gridy = 0; // Posición
        gbc.anchor = GridBagConstraints.EAST; // Alinear a la derecha
        add(new JLabel("Usuario:"), gbc);

        // Campo de Usuario
        gbc.gridx = 1; gbc.gridy = 0; // Posición
        gbc.fill = GridBagConstraints.HORIZONTAL; // Que ocupe todo el ancho
        gbc.weightx = 1.0; // Expansión horizontal
        JTextField campoUsuario = new JTextField(15);
        add(campoUsuario, gbc);

        // Etiqueta Contraseña
        gbc.gridx = 0; gbc.gridy = 1; // Posición
        gbc.anchor = GridBagConstraints.EAST;
        add(new JLabel("Contraseña:"), gbc);

        // Campo de Contraseña
        gbc.gridx = 1; gbc.gridy = 1;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        JPasswordField campoPassword = new JPasswordField(15);
        add(campoPassword, gbc);

        // Botón de Login
        gbc.gridx = 0; gbc.gridy = 2;
        gbc.gridwidth = 2; // Ocupar dos columnas
        gbc.fill = GridBagConstraints.CENTER; // Centrado
        JButton botonLogin = new JButton("Iniciar Sesión");
        add(botonLogin, gbc);

        setVisible(true);
    }

    public static void main(String[] args) {
        new LoginGridBag();
    }
}

🔹 Explicación:

1️⃣ Creamos la ventana con JFrame y le damos un tamaño de 300x200.
2️⃣ Establecemos GridBagLayout como el layout principal.
3️⃣ Creamos un objeto GridBagConstraints para definir posiciones.
4️⃣ Colocamos cada elemento en una celda específica usando gridx y gridy:

  • gridx = 0, gridy = 0 → Etiqueta «Usuario».
  • gridx = 1, gridy = 0 → Campo de texto para el usuario.
  • gridx = 0, gridy = 1 → Etiqueta «Contraseña».
  • gridx = 1, gridy = 1 → Campo de texto para la contraseña.
  • gridx = 0, gridy = 2, gridwidth = 2 → Botón «Iniciar Sesión».

5️⃣ Configuramos fill, weightx, anchor y gridwidth para mejorar la alineación.
6️⃣ Mostramos la ventana con setVisible(true).

Resultado: Se obtiene un formulario con distribución flexible, donde los elementos pueden expandirse si la ventana se redimensiona.


4. Añadiendo Componentes Básicos en Swing

Además de los botones (JButton), podemos usar otros componentes gráficos:

  • JLabel → Etiquetas de texto.
  • JTextField → Campos de texto para entrada de usuario.
  • JPasswordField → Campos de contraseña.
  • JTextArea → Áreas de texto más grandes.

También puedes mezclar Layouts si los combinas con JPanel, como vas a ver en el siguiente ejemplo.

Ejemplo 5: Formulario Simple de registro

📌 Objetivo: Crear un formulario de registro con:

  • BorderLayout → Organización principal de la ventana.
  • GridLayout → Organización de los campos de entrada.
  • FlowLayout → Botones alineados en la parte inferior.

📌 Distribución de la ventana:

  • Norte (BorderLayout.NORTH) → Etiqueta de título.
  • Centro (BorderLayout.CENTER) → Campos organizados con GridLayout.
  • Sur (BorderLayout.SOUTH) → Botones organizados con FlowLayout.
import javax.swing.*;
import java.awt.*;

public class RegistroApp extends JFrame {
    public RegistroApp() {
        setTitle("Registro de Usuario");
        setSize(400, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout()); // Layout principal

        // --- PARTE SUPERIOR: Título con JLabel ---
        JLabel titulo = new JLabel("Formulario de Registro", SwingConstants.CENTER);
        titulo.setFont(new Font("Arial", Font.BOLD, 18));
        add(titulo, BorderLayout.NORTH);

        // --- PARTE CENTRAL: Formulario con GridLayout ---
        JPanel panelFormulario = new JPanel();
        panelFormulario.setLayout(new GridLayout(3, 2, 10, 10)); // 3 filas, 2 columnas

        // Etiquetas y campos de entrada
        panelFormulario.add(new JLabel("Nombre:"));
        panelFormulario.add(new JTextField(15));

        panelFormulario.add(new JLabel("Correo:"));
        panelFormulario.add(new JTextField(15));

        panelFormulario.add(new JLabel("Contraseña:"));
        panelFormulario.add(new JPasswordField(15));

        add(panelFormulario, BorderLayout.CENTER);

        // --- PARTE INFERIOR: Botones con FlowLayout ---
        JPanel panelBotones = new JPanel();
        panelBotones.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10)); // Centrado

        JButton btnRegistrar = new JButton("Registrar");
        JButton btnCancelar = new JButton("Cancelar");

        panelBotones.add(btnRegistrar);
        panelBotones.add(btnCancelar);

        add(panelBotones, BorderLayout.SOUTH);

        setVisible(true);
    }

    public static void main(String[] args) {
        new RegistroApp();
    }
}

🔹 Explicación:

1️⃣ BorderLayout como Estructura Principal:

  • La ventana usa BorderLayout, lo que permite organizar componentes en Norte, Centro y Sur.

2️⃣ GridLayout en el Panel Central

  • GridLayout(3, 2, 10, 10)3 filas, 2 columnas, con un espaciado de 10px.
  • Contiene etiquetas y campos de texto, alineados automáticamente.

3️⃣ FlowLayout en el Panel Inferior

  • Los botones «Registrar» y «Cancelar» están en un JPanel con FlowLayout.CENTER, lo que los coloca en el centro con espaciado.

Ventajas de combinar Layouts:

  • BorderLayout estructura la ventana en zonas.
  • GridLayout organiza los campos de manera uniforme.
  • FlowLayout permite alinear los botones de forma natural.

5. Manejo de Eventos con ActionListener

Cuando el usuario interactúa con un componente (ejemplo: hace clic en un botón), necesitamos manejar el evento. Esto se hace con ActionListener. Aunque lo desarrollaremos más adelante, en el siguiente ejemplo puedes ver la forma más simple de programar un evento.

Ejemplo 6: Capturar el texto de un campo de texto

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class EventoFormulario extends JFrame {
    public EventoFormulario() {
        setTitle("Evento con Botón");
        setSize(300, 150);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new FlowLayout());

        JLabel etiqueta = new JLabel("Escribe algo:");
        add(etiqueta);

        JTextField campoTexto = new JTextField(15);
        add(campoTexto);

        JButton boton = new JButton("Mostrar");
        add(boton);

        // Agregamos un ActionListener al botón
        boton.addActionListener(e -> {
            String texto = campoTexto.getText();
            JOptionPane.showMessageDialog(this, "Has escrito: " + texto);
        });

        setVisible(true);
    }

    public static void main(String[] args) {
        new EventoFormulario();
    }
}

🔹 Explicación:

  • Se usa campoTexto.getText() para obtener el texto escrito.
  • Se muestra un mensaje emergente (JOptionPane.showMessageDialog).
  • boton.addActionListener(e -> { ... }) define qué hacer al hacer clic.

6. Conclusión y Próximos Pasos

En esta sesión hemos aprendido a:

  • Usar layouts para organizar componentes.
  • Crear etiquetas, botones y campos de texto en una ventana.
  • Manejar eventos con ActionListener.

📌 En la siguiente sesión exploraremos menús, diálogos y más interactividad con Swing. ¡Nos vemos pronto! 🚀


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.