# Máscaras e teclados

> EditMode (data/hora/moeda), máscara com '9', teclados nativos e o Keypad embutido.

Source: https://crossfly.dev/pt/docs/ui/forms-and-input/masks-and-keyboards — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Máscaras e teclados

O `EditMode` do campo controla **duas coisas ao mesmo tempo**: a **formatação** (máscara) e o
**teclado** que abre. É a peça central da entrada estruturada.

## `EditMode` → teclado
| `EditMode` | Formatação | Teclado que abre |
|---|---|---|
| `NORMAL` | nenhuma | teclado padrão do SO |
| `NUMERIC` | dígitos | numérico nativo (`Keypad` no desktop) |
| `DATE` | máscara de data | **DatePicker** |
| `TIME` | máscara de hora | **TimePicker** |
| `CURRENCY` | moeda (separadores) | **Keypad** calculadora |
| `PASSWORD` | oculta caracteres | teclado padrão |

## Exemplo completo (copiar, colar e rodar)
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;   // TextFieldStyle (config comportamental)

/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // Campo de data: máscara ligada abre o DatePicker ao tocar
      TextField data = new TextField().caption("Data");
      data.setMode(EditMode.DATE, true);      // maskedEdit=true → formata e abre DatePicker
      add(LAY_AUTO, data);

      // Campo de moeda: formata como moeda ao digitar
      TextField valor = new TextField().caption("Valor");
      valor.setMode(EditMode.CURRENCY, true);
      valor.<TextFieldStyle>getStyle().decimalPlaces(2);
      add(LAY_AUTO, valor);

      // Rótulo onde os valores lidos serão exibidos
      Label resultado = new Label("");
      add(LAY_AUTO, resultado);

      // NÃO há callback por tecla: leia getText() no envio.
      // getTextWithoutMask() devolve só os dígitos (bom p/ salvar no banco).
      Button enviar = new Button("Enviar");
      enviar.onAction(c -> resultado.setText(
         "Data = " + data.getText() + "  |  Valor = " + valor.getTextWithoutMask()));
      add(LAY_AUTO, enviar);
   }
}
```

> Os trechos abaixo mostram **só o miolo** (o que vai dentro de `onShow()`). Para rodar, coloque-os no esqueleto `MainWindow` acima.

## Ativar máscara automática
`setMode(mode, true)` liga a formatação em tempo real (`maskedEdit`):
```java
TextField data = new TextField().caption("Data");
data.setMode(EditMode.DATE, true);         // ao digitar, vira 15/03/2024 e abre o DatePicker

TextField valor = new TextField().caption("Valor");
valor.setMode(EditMode.CURRENCY, true);    // formata como moeda ao digitar
valor.<TextFieldStyle>getStyle().decimalPlaces(2);
```

## Máscara custom (o `'9'` é o dígito)
Numa máscara, cada `'9'` é uma posição de dígito; os demais caracteres são literais fixos:
```java
TextField cpf = new TextField().caption("CPF");
cpf.<TextFieldStyle>getStyle()
   .mask("999.999.999-99".toCharArray())    // 11 dígitos + separadores
   .mode(EditMode.NUMERIC, true);
// getText()          -> "123.456.789-00"  (com máscara)
// getTextWithoutMask()-> "12345678900"    (só dígitos)
```
Moeda pronta: `TextField.getDefaultCurrencyMask(int casasDecimais)` gera a máscara com os separadores
de milhar/decimal do locale.

## Escolher o teclado explicitamente
```java
campo.keyboard(Keyboard.NUMERIC);   // força numérico
campo.keyboard(Keyboard.NONE);      // nunca abre teclado (campo só-leitura visual)
```
`Keyboard` (em `UIConstants`): `NONE, DEFAULT, NUMERIC, KEYPAD, CALCULATOR, DATE, TIME`. `DEFAULT`
adota o teclado implícito no `EditMode` atual.

## Keypad embutido
`Keyboard.KEYPAD`/`CALCULATOR` usam o componente **`Keypad`** do próprio CrossFly (não o teclado do
SO) — útil em quiosques/PDV. Ele é aberto automaticamente pelo campo; para usá-lo avulso:
```java
new Keypad(meuCampo).show();        // teclado numérico ligado ao campo
```

## Boas práticas
- Salve no banco o **`getTextWithoutMask()`** (dígitos crus); exiba com máscara.
- Combine `mask(...)` com `mode(EditMode.NUMERIC, true)` para documentos (CPF, CEP, telefone).
- Em desktop, `NUMERIC` cai para o `Keypad` automaticamente — não assuma teclado nativo.

## Erros comuns
- Ligar `mode(EditMode.DATE)` **sem** `maskedEdit=true` → sem formatação automática.
- Persistir `getText()` (com pontos/traços) quando o back-end espera só dígitos.
- Máscara sem nenhum `'9'` → nenhum dígito é aceito.

## Veja também
- [Campos de texto](/docs/ui/forms-and-input/text-fields) · Catálogo: [DatePicker](/docs/ui/widgets/datepicker) · [TimePicker](/docs/ui/widgets/timepicker) · [Keypad](/docs/ui/widgets/keypad)
