# Whiteboard

> 自由绘图与捕获——签名、涂鸦——可调画笔颜色与粗细，并能导出成图片。

Source: https://crossfly.dev/zh/docs/ui/images-and-graphics/whiteboard — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Whiteboard

`Whiteboard` 是一个**用手指/鼠标自由绘图**的区域——经典用例是**签名捕获**。它已经处理好触摸事件并在内部累积笔画。

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

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.image.*;       // Image

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

      // 签名区占据剩余空间（LAY_FILL）。
      Whiteboard board = new Whiteboard();
      board.setPenColor(0xFF000000);   // 黑色画笔
      board.thick = true;              // 粗描边
      add(LAY_FILL, board);

      // 清除绘制的按钮。
      Button limpar = new Button("Limpar");
      limpar.onAction(c -> board.clear());
      add(LAY_AUTO, limpar);

      // 将绘制内容捕获为图片的按钮（例如：用于持久化）。
      Button salvar = new Button("Salvar");
      salvar.onAction(c -> {
         Image img = board.getImage();   // 当前绘制内容为 Image（若为空可能为 null）
         // ……持久化 img（例如：PNG）……
      });
      add(LAY_AUTO, salvar);
   }
}
```
> 下面的代码片段只展示**核心部分**（放进 `onShow()` 内的内容）。要运行它们，请把它们放入上面的 `MainWindow` 骨架中。

## 基本用法（签名）
```java
Whiteboard assinatura = new Whiteboard();
assinatura.setPenColor(0xFF000000);   // 黑色画笔
assinatura.thick = true;              // 粗描边
painel.add(0.5f, assinatura);         // 高度的 50%

Button limpar = new Button("Limpar");
limpar.onAction(c -> assinatura.clear());

Button salvar = new Button("Salvar");
salvar.onAction(c -> {
   Image img = assinatura.getImage();   // 绘制内容作为图片
   // ……持久化 img（例如：PNG）……
});
```

## API
| 成员 | 效果 |
|---|---|
| `setPenColor(int)` / `getPenColor()` | 画笔颜色（ARGB） |
| `thick`（`boolean` 字段） | `true` = 粗笔画 |
| `clear()` | 清除全部 |
| `getImage()` | 以 `Image` 形式返回当前绘图 |
| `setImage(Image)` | 加载一张底图（抛出 `ImageException`） |

## 最佳实践
- 给予**充裕的高度**（容器的比例或 `autoHeight`）——签名需要空间。
- 始终提供一个**清除**按钮。
- 保存时使用 `getImage()`，并在转换/持久化时处理异常。

## 常见错误
- 区域过小 → 签名难以辨认。
- 忘记 `setImage(Image)` 会抛出 `ImageException`（受检异常）。
- 与 `ImageView`（仅显示）混淆——`Whiteboard` **捕获**绘图。

## 另见
- [图像](/docs/ui/images-and-graphics/images) · [自定义绘图](/docs/ui/images-and-graphics/custom-drawing)
- 目录：[Whiteboard](/docs/ui/widgets/whiteboard) · 参考：第 18 章 — 图像
