Layout managers
Los layout managers (gestores de disposición) controlan cómo se posicionan y dimensionan los componentes dentro de un contenedor. Usar layouts es la forma correcta de hacer interfaces responsivas que se adapten al redimensionado de la ventana.

FlowLayout
Coloca los componentes en fila, de izquierda a derecha, pasando a la siguiente línea cuando no caben.
// Alineación: LEFT, CENTER (defecto), RIGHT, LEADING, TRAILING
// Hgap: espacio horizontal entre componentes
// Vgap: espacio vertical entre filas
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
panel.add(new JLabel("Nombre:"));
panel.add(new JTextField(15));
panel.add(new JButton("Buscar"));
Cuándo usarlo: Barras de botones simples, toolbars horizontales, grupos pequeños de componentes.
BorderLayout
Divide el contenedor en 5 zonas: NORTH, SOUTH, EAST, WEST y CENTER.
JPanel panel = new JPanel(new BorderLayout(5, 5)); // hgap, vgap
panel.add(new JLabel("Cabecera", JLabel.CENTER), BorderLayout.NORTH);
panel.add(new JScrollPane(new JTextArea()), BorderLayout.CENTER); // ocupa el espacio restante
panel.add(new JList<>(), BorderLayout.EAST);
panel.add(new JTextField("Buscar..."), BorderLayout.SOUTH);
// WEST no se usa en este ejemplo
Reglas:
- Solo un componente por zona.
CENTERse expande para llenar todo el espacio disponible.- Las zonas no utilizadas no ocupan espacio.
JFrameusaBorderLayoutpor defecto.
Cuándo usarlo: Estructura clásica de aplicación (cabecera + contenido central + barra de estado).
GridLayout
Coloca los componentes en una cuadrícula de filas × columnas, todos del mismo tamaño.
// 3 filas, 2 columnas, 5px horizontal, 5px vertical entre celdas
JPanel panel = new JPanel(new GridLayout(3, 2, 5, 5));
panel.add(new JLabel("Nombre:"));
panel.add(new JTextField());
panel.add(new JLabel("Email:"));
panel.add(new JTextField());
panel.add(new JLabel("Teléfono:"));
panel.add(new JTextField());
Reglas:
- Si pones
0en filas: las filas crecen automáticamente. - Todos los componentes tienen exactamente el mismo tamaño.
Cuándo usarlo: Formularios simples, teclados numéricos, calculadoras, tableros de juego.
GridBagLayout
El layout más potente y flexible de Swing. Permite que cada componente ocupe diferentes números de celdas, con pesos de expansión independientes.
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
// Configuración base (se reutiliza modificando campos)
gbc.insets = new Insets(5, 5, 5, 5); // Margen exterior (top, left, bottom, right)
gbc.fill = GridBagConstraints.HORIZONTAL; // Cómo rellenar la celda
// Etiqueta Nombre (columna 0, fila 0)
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 0; // No se expande horizontalmente
panel.add(new JLabel("Nombre:"), gbc);
// Campo Nombre (columna 1, fila 0)
gbc.gridx = 1;
gbc.gridy = 0;
gbc.weightx = 1.0; // Se expande para llenar el espacio
panel.add(new JTextField(), gbc);
// Etiqueta Email (columna 0, fila 1)
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weightx = 0;
panel.add(new JLabel("Email:"), gbc);
// Campo Email (columna 1, fila 1)
gbc.gridx = 1;
gbc.gridy = 1;
gbc.weightx = 1.0;
panel.add(new JTextField(), gbc);
// Botón que ocupa 2 columnas (columna 0-1, fila 2)
gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridwidth = 2; // Ocupa 2 columnas
gbc.weightx = 0;
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.CENTER;
panel.add(new JButton("Enviar"), gbc);
Propiedades de GridBagConstraints
| Propiedad | Descripción |
|---|---|
gridx | Columna (empieza en 0). RELATIVE = siguiente columna automático |
gridy | Fila (empieza en 0) |
gridwidth | Número de columnas que ocupa el componente |
gridheight | Número de filas que ocupa el componente |
weightx | Peso de expansión horizontal (0 = no crece, 1.0 = crece todo) |
weighty | Peso de expansión vertical |
fill | NONE, HORIZONTAL, VERTICAL, BOTH |
anchor | Posición si el componente no llena la celda: CENTER, NORTH... |
insets | Margen exterior del componente |
ipadx/ipady | Margen interior (padding) del componente |
BoxLayout
Organiza los componentes en una fila o columna, respetando los tamaños preferidos de cada uno.
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); // Columna vertical
// BoxLayout.X_AXIS → fila horizontal
panel.add(new JLabel("Título"));
panel.add(Box.createVerticalStrut(10)); // Espacio rígido de 10px
panel.add(new JTextField());
panel.add(Box.createRigidArea(new Dimension(0, 10))); // Equivalente
panel.add(Box.createVerticalGlue()); // Espacio flexible (empuja hacia arriba)
panel.add(new JButton("Aceptar"));
Nunca uses coordenadas absolutas (setLayout(null) + setBounds()): la interfaz se rompe al cambiar el tamaño o la resolución. Solo tiene sentido en prototipados rápidos.
Espaciadores de Box
| Método | Descripción |
|---|---|
Box.createHorizontalStrut(n) | Espacio rígido horizontal de n píxeles |
Box.createVerticalStrut(n) | Espacio rígido vertical de n píxeles |
Box.createRigidArea(Dimension) | Espacio rígido con ancho y alto |
Box.createHorizontalGlue() | Espacio flexible horizontal (llena el hueco) |
Box.createVerticalGlue() | Espacio flexible vertical |
Cuándo usarlo: Paneles laterales, diálogos con botones alineados, menús verticales.
CardLayout
Permite apilar paneles y mostrar solo uno a la vez. Ideal para asistentes (wizards) o paneles con pestañas personalizadas.
JPanel contenedor = new JPanel();
CardLayout card = new CardLayout();
contenedor.setLayout(card);
// Añadir "páginas" con nombre
contenedor.add(new JPanel() {{ add(new JLabel("Pantalla 1")); }}, "pagina1");
contenedor.add(new JPanel() {{ add(new JLabel("Pantalla 2")); }}, "pagina2");
contenedor.add(new JPanel() {{ add(new JLabel("Pantalla 3")); }}, "pagina3");
// Navegar entre páginas
card.show(contenedor, "pagina2"); // Mostrar página específica
card.next(contenedor); // Siguiente
card.previous(contenedor); // Anterior
card.first(contenedor); // Primera
card.last(contenedor); // Última
SpringLayout
Layout avanzado que define posiciones mediante restricciones de distancia entre los bordes de los componentes. Muy flexible pero verboso.
JPanel panel = new JPanel(new SpringLayout());
JLabel lbl = new JLabel("Nombre:");
JTextField txt = new JTextField(15);
panel.add(lbl);
panel.add(txt);
SpringLayout layout = (SpringLayout) panel.getLayout();
// El borde WEST de lbl está a 5px del borde WEST del panel
layout.putConstraint(SpringLayout.WEST, lbl, 5, SpringLayout.WEST, panel);
// El borde NORTH de lbl está a 5px del borde NORTH del panel
layout.putConstraint(SpringLayout.NORTH, lbl, 5, SpringLayout.NORTH, panel);
// El borde WEST de txt está a 10px del borde EAST de lbl
layout.putConstraint(SpringLayout.WEST, txt, 10, SpringLayout.EAST, lbl);
// Alinear verticalmente lbl y txt
layout.putConstraint(SpringLayout.NORTH, txt, 0, SpringLayout.NORTH, lbl);
Composición de layouts (el patrón real)
En aplicaciones reales se combinan layouts anidando paneles.
// Panel principal con BorderLayout
JPanel main = new JPanel(new BorderLayout(5, 5));
// Cabecera
JLabel header = new JLabel("Mi App", JLabel.CENTER);
header.setFont(new Font("Arial", Font.BOLD, 20));
main.add(header, BorderLayout.NORTH);
// Formulario central con GridBagLayout
JPanel form = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(4, 4, 4, 4);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0; c.gridy = 0; c.weightx = 0;
form.add(new JLabel("Usuario:"), c);
c.gridx = 1; c.weightx = 1;
form.add(new JTextField(20), c);
c.gridx = 0; c.gridy = 1; c.weightx = 0;
form.add(new JLabel("Contraseña:"), c);
c.gridx = 1; c.weightx = 1;
form.add(new JPasswordField(20), c);
main.add(form, BorderLayout.CENTER);
// Barra de botones con FlowLayout alineado a la derecha
JPanel botones = new JPanel(new FlowLayout(FlowLayout.RIGHT));
botones.add(new JButton("Cancelar"));
botones.add(new JButton("Aceptar"));
main.add(botones, BorderLayout.SOUTH);
Bordes decorativos con BorderFactory
Los bordes no son layouts, pero complementan la organización visual:
JPanel panel = new JPanel();
// Tipos de borde
panel.setBorder(BorderFactory.createLineBorder(Color.GRAY, 1));
panel.setBorder(BorderFactory.createEtchedBorder());
panel.setBorder(BorderFactory.createRaisedBevelBorder());
panel.setBorder(BorderFactory.createLoweredBevelBorder());
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // Solo padding
// TitledBorder — borde con título (muy común en formularios)
panel.setBorder(BorderFactory.createTitledBorder("Datos personales"));
// Borde compuesto
panel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Opciones"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)
));