跳到内容
CrossFly 是 100% 开源在 GitHub 关注我们
CrossFlyCrossFly
开始使用

本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。

Whiteboard

Whiteboard 是一个自由绘图表面:用户拖动手指/指针,组件记录这些点,平滑笔迹(相邻点的加权平均),并将其渲染到内部的 Image 上。它是签名捕获、手写批注和小型草图的基础。每一笔完成后(在 onTouchUp 时)都会“烧录”到图像上,因此历史记录会累积而无需在每一帧重新处理所有点。

你可以控制画笔颜色(setPenColor)、粗细(thick 字段),并且可以清除(clear())或导出/设置背景图像(getImage/setImage)。

🟢 · 包: dev.crossfly.ui · 继承: Component · 样式: ComponentStyle(默认白色背景)

何时使用

  • 捕获一个签名或一幅自由手绘。
  • 在现有图像上进行批注(通过 setImage 传入)。

何时不要使用

  • 显示/绘制结构化数据 → 使用 chartview。

外观

与组件同尺寸的白色背景(backColor)。笔迹是平滑的线条,粗细为 Styles.fontHeight/3(粗)或 Styles.fontHeight/10(细),采用画笔颜色(alpha 被强制为不透明)。该组件具有 hasPan(true),即捕获拖动手势以进行绘制。

完整示例(复制、粘贴并运行)

Whiteboard 是一个普通组件:用 add(LAY_FILL, ...) 直接放入屏幕以占据主体。此示例复用了基本用法(蓝色画笔、粗笔迹),并添加了一个清除按钮。

package com.exemplo;

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

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

      Whiteboard board = new Whiteboard();
      board.setPenColor(0x0000FF);   // 蓝色(绘制时 alpha 被强制为不透明)
      board.thick = true;            // 粗描边

      Button limpar = new Button("Limpar")
         .onAction(c -> board.clear());
      add(LAY_AUTO, limpar);

      add(LAY_FILL, board);          // 占据屏幕主体
   }
}

下面的片段仅展示核心部分(放入 onShow() 内的内容)。要运行它们,请将其放入上面的 MainWindow 骨架中。

基本用法

Whiteboard board = new Whiteboard();
board.setPenColor(0x0000FF);   // 蓝色(绘制时 alpha 被强制为不透明)
board.thick = true;            // 粗描边
container.add(LAY_FILL, board);

// 在其他地方,一个用于清除的按钮:
btnLimpar.onAction(c -> board.clear());

构造函数

构造函数 描述
Whiteboard() 创建具有白色背景和 hasPan(true) 的表面(可立即绘制)。

属性与自定义

属性 / 方法 类型 默认值 作用
setPenColor(int) void BLACK 设置画笔颜色(绘制时强制不透明 alpha)。
getPenColor() int — 返回当前画笔颜色。
thick boolean(字段) false true = 粗笔迹(fontHeight/3);false = 细笔迹(fontHeight/10)。
clear() void — 清除图像和累积的点。
getImage() Image null 返回绘图图像(如果未绘制任何内容,则可能为 null)。
setImage(Image) void — 设置背景/基础图像(传入 null 表示空白表面)。throws ImageException。
Whiteboard.debugPoints boolean 静态 false 调试:显示点数/渲染时间。

回调与事件

Whiteboard 在内部处理手势;不暴露“笔迹完成”回调。

事件(内部) 行为
onTouchDown(x,y,button) 开始一笔新笔迹并记录第一个点。
onPan(x,y,dx,dy) 在用户拖动时累积点并重绘。
onTouchUp(x,y,button) 结束笔迹并将绘图“烧录”到内部的 Image 上。

状态

  • 绘制中:在 onTouchDown 和 onTouchUp 之间,点位于一个临时缓冲区中,并在每次 onPan 时被平滑/渲染。
  • 已固化:在 onTouchUp 时,笔迹被写入 Image 并清空缓冲区(每帧成本不随笔迹总数增长)。

带颜色选择和导出的签名面板

Whiteboard assinatura = new Whiteboard();
assinatura.thick = false;                 // 用于签名的细笔画
container.add(LAY_FILL, assinatura);

btnPreto.onAction(c -> assinatura.setPenColor(0x000000));
btnAzul.onAction (c -> assinatura.setPenColor(0x0000FF));
btnLimpar.onAction(c -> assinatura.clear());

// 确认后,取回生成的图像:
btnOk.onAction(c -> {
   Image desenho = assinatura.getImage();   // 如果什么都没画,可能为 null
   if (desenho != null)
      salvarAssinatura(desenho);
});

最佳实践

  • 签名优先使用 thick = false(笔迹更精确),大幅草图使用 thick = true。
  • 导出前务必检查 getImage() != null:如果用户未绘制任何内容,图像仍为 null。
  • 提供一个 clear() 按钮 —— 没有按笔迹的“撤销”功能。

常见错误

  • 传入带有显式 alpha 的颜色并期望透明:绘制强制不透明 alpha(0xFF000000 | cor)。
  • 期望有笔迹回调:在交互后使用方法(getImage);没有笔迹完成的 onAction。

另请参阅

这个页面有帮助吗?