# Pensando en componentes

> Component como base, ciclo de vida (onAdd/onRemove), composición y un componente custom con bind.

Source: https://crossfly.dev/es/docs/learn/thinking-in-components — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# 3. Pensando en componentes

> **Lo que vas a aprender:** `Component` como base de todo, el ciclo de vida, la composición y cómo crear
> un componente reutilizable. **Prerrequisitos:** [Ventanas y navegación](/docs/learn/windows-and-navigation).

## Ejemplo completo (copiar, pegar y ejecutar)
Un componente reutilizable (`CardTarefa`) montado una vez en `onAdd` y re-vinculado por datos vía
`bind(...)`. La ventana crea tres cards con datos diferentes. Compila tal cual.
```java
package com.exemplo;

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

public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      CardTarefa c1 = new CardTarefa(); add(LAY_AUTO, c1); c1.bind(new Tarefa("Comprar pão"));
      CardTarefa c2 = new CardTarefa(); add(LAY_AUTO, c2); c2.bind(new Tarefa("Pagar conta"));
      CardTarefa c3 = new CardTarefa(); add(LAY_AUTO, c3); c3.bind(new Tarefa("Estudar CrossFly"));
   }
}

class Tarefa                                             // modelo mínimo
{
   final String titulo;
   Tarefa(String titulo) { this.titulo = titulo; }
}

class CardTarefa extends Component
{
   private final Label titulo = new Label();

   @Override
   public void onAdd(boolean firstTime) throws Exception  // monta la estructura UNA vez
   {
      super.onAdd(firstTime);
      setLayout(new HorizontalLayout());
      add(LAY_FILL, titulo);
   }

   public void bind(Tarefa t)                             // re-vincula por datos (barato)
   {
      titulo.setText(t.titulo);
      repaint();
   }
}
```
> Los fragmentos de abajo muestran **solo el núcleo** (lo que va dentro de `onShow()`). Para ejecutar, colócalos en el esqueleto `MainWindow` de arriba.

## Todo es `Component`, container = Component + Layout
Un `Label` es un `Component`. Un `Button` es un `Component`. Cualquier `Component` se convierte en **container** al
recibir un `Layout`, y `add(...)` delega la disposición al layout.
```java
Component painel = new Component();
painel.setLayout(new VerticalLayout());
painel.add(LAY_AUTO, new Label("Título"));
```

## Ciclo de vida
| Gancho | Cuándo | Uso |
|---|---|---|
| `onAdd(boolean firstTime)` | al entrar en el árbol | inicializar (recursos solo la 1ª vez → `firstTime`) |
| `onRemove()` | al salir | liberar timers/listeners |

## Componente reutilizable con `bind(...)`
El patrón de "card" reciclable: monta la estructura **una vez** (en `onAdd`) y **re-vincula** por datos:
```java
public class CardTarefa extends Component {
   private final Label titulo = new Label();
   @Override public void onAdd(boolean firstTime) throws Exception {
      super.onAdd(firstTime);
      setLayout(new HorizontalLayout());
      add(LAY_FILL, titulo);
   }
   public void bind(Tarefa t) {      // re-vincula por datos (barato, llamado muchas veces)
      titulo.setText(t.titulo);
      repaint();
   }
}
```
Ese es exactamente el patrón que usa `VirtualListView` para reciclar views (ver
[Cargando datos](/docs/learn/loading-data)).

## Construyes en este paso
El componente **`CardTarefa`** reutilizable — montado una vez, re-vinculado por tarea.

## Recapitulando
`Component` es la base; container = `Component` + `Layout`; inicializa en `onAdd(firstTime)`, libera en
`onRemove()`; los componentes custom separan **montar** (una vez) de **vincular** (`bind`, muchas veces).

## Próximos pasos
→ [Layouts](/docs/learn/layouts)

## Ver también
- Concepto: [Todo es un Component](/docs/concepts/everything-is-a-component) · [Ciclo de vida](/docs/concepts/lifecycle)
