# 如何打开数字键盘

> 在系统原生数字键盘、内置 Keypad 或计算器之间选择。

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

# 如何打开数字键盘

**用途。** 让字段在获得焦点时打开一个只有数字的键盘——系统原生数字键盘、CrossFly 内置的 Keypad，或计算器变体。

## 用到的 API
- `campo.keyboard(Keyboard.NUMERIC)` — 流式快捷方法（等价于 `setKeyboard`）。可用类型（枚举 `Keyboard`）：`NONE`、`DEFAULT`、`NUMERIC`、`KEYPAD`、`CALCULATOR`、`DATE`、`TIME`。
- `campo.setKeyboard(Keyboard kbd)` — 设置键盘。传入 `Keyboard.DEFAULT` 会让字段采用当前 `EditMode` 隐含的键盘（`mode.getKeyboard()`）。
- `campo.<TextFieldStyle>getStyle().mode(EditMode.NUMERIC)` — 设置数字模式；作为副作用，`mode(...)` **总是**从模式推导出键盘（`NUMERIC → NUMERIC`）。要覆盖它，请在 `mode(...)` **之后**调用 `keyboard(...)`。

如何选择：

| 键盘 | 行为 |
|---|---|
| `NUMERIC` | 系统原生数字键盘。在桌面端回退为 `KEYPAD`。 |
| `KEYPAD` | CrossFly 的 `Keypad` 组件（内置的按键网格）。 |
| `CALCULATOR` | 处于计算器模式的 `Keypad`（`isCalculator(true)`）。 |

> 在桌面端（`Device.platform.isDesktop()`），由于没有原生虚拟键盘，`NUMERIC` 会在 `showInput()` 中自动转换为 `KEYPAD`。

## 完整示例（复制、粘贴并运行）
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;   // TextFieldStyle（在样式中配置）

/** 可执行的主界面。将 launcher 指向此类（classname）并运行：gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // 1) 原生数字键盘（桌面端为 KEYPAD）
      TextField idade = new TextField("");
      idade.caption("Idade");
      idade.<TextFieldStyle>getStyle().mode(EditMode.NUMERIC);

      // 2) 强制使用内置 Keypad，与模式无关
      TextField pin = new TextField("");
      pin.caption("PIN");
      pin.keyboard(Keyboard.KEYPAD);

      // 3) 计算器
      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);
   }
}
```

> 下面的片段只展示**核心部分**。要运行它，请将其放入上面的 `MainWindow` 骨架中。

## 最小片段
```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) 原生数字键盘（桌面端为 KEYPAD）
TextField idade = new TextField("");
idade.caption("Idade");
idade.<TextFieldStyle>getStyle().mode(EditMode.NUMERIC);

// 2) 强制使用内置 Keypad，与模式无关
TextField pin = new TextField("");
pin.caption("PIN");
pin.keyboard(Keyboard.KEYPAD);

// 3) 计算器
TextField total = new TextField("");
total.keyboard(Keyboard.CALCULATOR);
```

要在打开键盘之外还限制只能输入数字，请与 `validChars` 结合使用（参见[验证字段](/docs/cookbook/forms/validar-campo)）：
```java
idade.<TextFieldStyle>getStyle()
   .mode(EditMode.NUMERIC)
   .validChars("0123456789")
   .maxLength(3);
```

## 深入了解
- [掩码与键盘](/docs/ui/forms-and-input/masks-and-keyboards) · [Keypad](/docs/ui/widgets/keypad)
- 姊妹配方：[货币掩码](/docs/cookbook/forms/mascara-moeda) · [验证字段](/docs/cookbook/forms/validar-campo)
- 权威来源：第 14 章 — 基础控件 · [枚举 (UIConstants)](/docs/reference/enums-uiconstants)
