Pular para o conteúdo
CrossFly é 100% open sourceSiga no GitHub
CrossFlyCrossFly
Começar

Whiteboard

Whiteboard é uma superfície de desenho livre: o usuário arrasta o dedo/ponteiro e o componente registra os pontos, suaviza o traço (média ponderada dos vizinhos) e o renderiza sobre uma Image interna. É a base para captura de assinatura, anotações à mão e pequenos rascunhos. Cada traço concluído (no onTouchUp) é “queimado” na imagem, de modo que o histórico acumula sem reprocessar todos os pontos a cada quadro.

Você controla a cor da caneta (setPenColor), a espessura (campo thick) e pode limpar (clear()) ou exportar/definir a imagem de fundo (getImage/setImage).

🟢 · Pacote: dev.crossfly.ui · Estende: Component · Estilo: ComponentStyle (fundo branco por default)

Quando usar

  • Capturar uma assinatura ou um desenho à mão livre.
  • Anotar sobre uma imagem existente (passe-a via setImage).

Quando NÃO usar

  • Exibir/plotar dados estruturados → use chartview.

Aparência

Fundo branco (backColor) do tamanho do componente. Os traços são linhas suavizadas com espessura Styles.fontHeight/3 (grosso) ou Styles.fontHeight/10 (fino), na cor da caneta (com alpha forçado para opaco). O componente tem hasPan(true), ou seja, captura o gesto de arrastar para desenhar.

Exemplo completo (copiar, colar e rodar)

Whiteboard é um componente comum: entra direto na tela com add(LAY_FILL, ...) para ocupar o corpo. O exemplo reutiliza o uso básico (caneta azul, traço grosso) e adiciona um botão para limpar.

package com.exemplo;

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

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

      Whiteboard board = new Whiteboard();
      board.setPenColor(0x0000FF);   // azul (o alpha é forçado para opaco no desenho)
      board.thick = true;            // traço grosso

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

      add(LAY_FILL, board);          // ocupa o corpo da tela
   }
}

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

Uso básico

Whiteboard board = new Whiteboard();
board.setPenColor(0x0000FF);   // azul (o alpha é forçado para opaco no desenho)
board.thick = true;            // traço grosso
container.add(LAY_FILL, board);

// Em outro lugar, um botão para limpar:
btnLimpar.onAction(c -> board.clear());

Construtores

Construtor Descrição
Whiteboard() Cria a superfície com fundo branco e hasPan(true) (pronta para desenho).

Propriedades e personalização

Propriedade / método Tipo Padrão O que faz
setPenColor(int) void BLACK Define a cor da caneta (o desenho força alpha opaco).
getPenColor() int — Retorna a cor atual da caneta.
thick boolean (campo) false true = traço grosso (fontHeight/3); false = fino (fontHeight/10).
clear() void — Limpa a imagem e os pontos acumulados.
getImage() Image null Retorna a imagem de desenho (pode ser null se nada foi desenhado).
setImage(Image) void — Define a imagem de fundo/base (passe null para superfície vazia). throws ImageException.
Whiteboard.debugPoints boolean estático false Depuração: exibe contagem de pontos/tempo de renderização.

Callbacks e eventos

Whiteboard trata os gestos internamente; não expõe um callback de “traço concluído”.

Evento (interno) Comportamento
onTouchDown(x,y,button) Inicia um novo traço e grava o primeiro ponto.
onPan(x,y,dx,dy) Acumula pontos enquanto o usuário arrasta e repinta.
onTouchUp(x,y,button) Finaliza o traço e “queima” o desenho na Image interna.

Estados

  • desenhando: entre onTouchDown e onTouchUp, os pontos ficam em um buffer temporário e são suavizados/renderizados a cada onPan.
  • consolidado: no onTouchUp, o traço é gravado na Image e o buffer é limpo (o custo por quadro não cresce com o total de traços).

Painel de assinatura com seleção de cor e exportação

Whiteboard assinatura = new Whiteboard();
assinatura.thick = false;                 // traço fino para assinar
container.add(LAY_FILL, assinatura);

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

// Ao confirmar, recupere a imagem resultante:
btnOk.onAction(c -> {
   Image desenho = assinatura.getImage();   // pode ser null se nada foi desenhado
   if (desenho != null)
      salvarAssinatura(desenho);
});

Boas práticas

  • Prefira thick = false para assinaturas (traço mais preciso) e thick = true para rascunhos amplos.
  • Sempre verifique getImage() != null antes de exportar: se o usuário não desenhou nada, a imagem ainda é null.
  • Ofereça um botão de clear() — não há “desfazer” por traço.

Erros comuns

  • Passar uma cor com alpha explícito esperando transparência: o desenho força alpha opaco (0xFF000000 | cor).
  • Esperar um callback de traço: use os métodos (getImage) após a interação; não há onAction de conclusão de traço.

Veja também

Esta página foi útil?