# Cómo abrir un teclado numérico

> Elegir entre teclado numérico nativo, Keypad integrado o calculadora.

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

# Cómo abrir un teclado numérico

**Propósito.** Hacer que el campo abra un teclado solo de números al recibir el foco — teclado numérico nativo del sistema, el Keypad integrado de CrossFly, o la variante calculadora.

## APIs usadas
- `campo.keyboard(Keyboard.NUMERIC)` — atajo fluido (equivalente a `setKeyboard`). Tipos disponibles (enum `Keyboard`): `NONE`, `DEFAULT`, `NUMERIC`, `KEYPAD`, `CALCULATOR`, `DATE`, `TIME`.
- `campo.setKeyboard(Keyboard kbd)` — define el teclado. Pasar `Keyboard.DEFAULT` hace que el campo adopte el teclado implícito por el `EditMode` actual (`mode.getKeyboard()`).
- `campo.<TextFieldStyle>getStyle().mode(EditMode.NUMERIC)` — define el modo numérico; como efecto, `mode(...)` **siempre** deriva el teclado del modo (`NUMERIC → NUMERIC`). Para sobrescribir, llama a `keyboard(...)` DESPUÉS de `mode(...)`.

Cuál elegir:

| Teclado | Comportamiento |
|---|---|
| `NUMERIC` | Teclado numérico nativo del SO. En escritorio recae en `KEYPAD`. |
| `KEYPAD` | Componente `Keypad` de CrossFly (rejilla de teclas integrada). |
| `CALCULATOR` | `Keypad` en modo calculadora (`isCalculator(true)`). |

> En escritorio (`Device.platform.isDesktop()`), `NUMERIC` se convierte automáticamente a `KEYPAD` en `showInput()`, ya que no hay teclado virtual nativo.

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

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;   // TextFieldStyle (config en el estilo)

/** 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());

      // 1) Teclado numérico nativo (KEYPAD en desktop)
      TextField idade = new TextField("");
      idade.caption("Idade");
      idade.<TextFieldStyle>getStyle().mode(EditMode.NUMERIC);

      // 2) Forzar el Keypad incrustado, independiente del modo
      TextField pin = new TextField("");
      pin.caption("PIN");
      pin.keyboard(Keyboard.KEYPAD);

      // 3) Calculadora
      TextField total = new TextField("");
      total.caption("Total");
      total.keyboard(Keyboard.CALCULATOR);

      Label resultado = new Label("");

      Button enviar = new Button("Enviar");
      enviar.onAction(o ->
         resultado.setText("Idade: " + idade.getText()
            + " · PIN: " + pin.getText()
            + " · Total: " + total.getText()));

      add(LAY_FILL, idade);
      add(LAY_FILL, pin);
      add(LAY_FILL, total);
      add(LAY_AUTO, enviar);
      add(LAY_FILL, resultado);
   }
}
```

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

## Fragmento mínimo
```java
import dev.crossfly.ui.*;
import dev.crossfly.ui.style.*;
import static dev.crossfly.ui.UIConstants.EditMode;
import static dev.crossfly.ui.UIConstants.Keyboard;

// 1) Teclado numérico nativo (KEYPAD en desktop)
TextField idade = new TextField("");
idade.caption("Idade");
idade.<TextFieldStyle>getStyle().mode(EditMode.NUMERIC);

// 2) Forzar el Keypad incrustado, independiente del modo
TextField pin = new TextField("");
pin.caption("PIN");
pin.keyboard(Keyboard.KEYPAD);

// 3) Calculadora
TextField total = new TextField("");
total.keyboard(Keyboard.CALCULATOR);
```

Para restringir a dígitos además de abrir el teclado, combínalo con `validChars` (ver [Validar un campo](/docs/cookbook/forms/validar-campo)):
```java
idade.<TextFieldStyle>getStyle()
   .mode(EditMode.NUMERIC)
   .validChars("0123456789")
   .maxLength(3);
```

## Profundiza
- [Máscaras y teclados](/docs/ui/forms-and-input/masks-and-keyboards) · [Keypad](/docs/ui/widgets/keypad)
- Recetas hermanas: [Máscara de moneda](/docs/cookbook/forms/mascara-moeda) · [Validar un campo](/docs/cookbook/forms/validar-campo)
- Fuente canónica: Capítulo 14 — Widgets básicos · [Enums (UIConstants)](/docs/reference/enums-uiconstants)
