# Cómo crear pestañas (TabBar)

> Montar una barra de pestañas con contenido por pestaña y reaccionar al cambio de pestaña.

Source: https://crossfly.dev/es/docs/cookbook/ui/abas — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Cómo crear pestañas (TabBar)

**Propósito.** Organizar el contenido en páginas conmutables mediante una barra de pestañas, con
indicador animado y deslizamiento horizontal entre páginas. Úsalo para secciones de nivel superior
(Inicio / Buscar / Perfil) o para agrupar contenido relacionado sin navegación de pantalla.

## APIs usadas
- `new TabBar(TabBar.Tab... tabs)` — crea la barra a partir de descriptores de pestaña.
- `new TabBar.Tab(String text)` — pestaña solo texto.
- `new TabBar.Tab(Icon icon)` — pestaña solo icono.
- `new TabBar.Tab(String text, Icon icon)` — pestaña con texto e icono (texto debajo del icono por defecto).
- `tabBar.setContent(Component... contents)` — define el contenido de cada pestaña; **la cantidad debe coincidir con el número de pestañas** (si no, lanza `IllegalArgumentException`).
- `tabBar.onTabChanged(TabBar.TabChangedListener listener)` — callback `onTabChanged(int index)` invocado cuando la pestaña activa cambia (por toque o por deslizamiento).
- `tabBar.setActiveTab(int index)` — cambia la pestaña programáticamente (anima el indicador y desplaza el contenido).
- `tabBar.getActiveIndex()` — índice de la pestaña activa.

## Ejemplo completo (copiar, pegar y ejecutar)
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // Pestañas solo texto (autónomas, sin depender de glyphs de MaterialIcon)
      TabBar tabBar = new TabBar(
         new TabBar.Tab("Início"),
         new TabBar.Tab("Buscar"),
         new TabBar.Tab("Perfil"));

      // Un Component de contenido por pestaña, en el MISMO orden que las pestañas
      Component telaInicio = new Label("Conteúdo: Início");
      Component telaBusca  = new Label("Conteúdo: Buscar");
      Component telaPerfil = new Label("Conteúdo: Perfil");

      tabBar.setContent(
         telaInicio,
         telaBusca,
         telaPerfil);

      tabBar.onTabChanged(index ->
      {
         // ej.: cargar datos bajo demanda cuando cambia la pestaña
         if (index == 1) carregarBusca();
      });

      add(LAY_FILL, tabBar);
   }

   private void carregarBusca()
   {
      // ... cargar datos de la pestaña Buscar bajo demanda ...
   }
}
```

> El fragmento de abajo muestra **solo el núcleo**. Para ejecutarlo, colócalo en el esqueleto `MainWindow` de arriba.

## Fragmento mínimo
```java
TabBar tabBar = new TabBar(
   new TabBar.Tab("Início",  new MaterialIcon("")),
   new TabBar.Tab("Buscar",  new MaterialIcon("")),
   new TabBar.Tab("Perfil",  new MaterialIcon("")));

// Un Component de contenido por pestaña, en el MISMO orden que las pestañas
tabBar.setContent(
   telaInicio,
   telaBusca,
   telaPerfil);

tabBar.onTabChanged(index ->
{
   // ej.: cargar datos bajo demanda cuando cambia la pestaña
   if (index == 1) carregarBusca();
});

add(tabBar);

// Cambiar de pestaña por código, si hace falta:
tabBar.setActiveTab(2);   // va a "Perfil"
```

> **Nota de verificación (código 2026).** Confirmado en la fuente: `TabBar(Tab...)`,
> `setContent(Component...)`, `onTabChanged(TabChangedListener)`, `setActiveTab(int)`.
> Detalles de comportamiento: la barra de pestañas se desliza horizontalmente cuando las pestañas
> no caben; deslizar el panel de contenido cambia la pestaña activa y mueve el indicador; el
> posicionamiento de las pestañas (arriba vs. abajo) y el estilo del indicador provienen de la `TabBarStyle`
> del `Skin` activo (ej.: `IOSSkin` coloca las pestañas abajo). Si `setContent` no se
> invoca, la barra muestra solo las pestañas sin panel de contenido.

## Profundiza
- Página del widget: [TabBar](/docs/ui/widgets/tabbar) · Fuente canónica: Capítulo 14
- Navegación entre pantallas (alternativa a las pestañas): [Navegación](/docs/ui/navigation)
