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

Como ler um QR Code ou código de barras

Propósito. Abrir a câmera e ler um QR Code ou código de barras ao vivo com o BarcodePicker, ou decodificar um código a partir de uma Image já capturada com CameraBarcode.

APIs usadas

  • BarcodePicker(String title, BarcodeFormat... formats) — janela abstrata de leitura ao vivo; você estende e implementa onBarcode(BarcodeFormat, String). formats vazio = aceita todos.
  • abstract void onBarcode(BarcodeFormat format, String code) — chamado a cada código novo decodificado que passa no filtro de formatos.
  • BarcodePicker.formats1D / formats2D (arrays estáticos) — conjuntos prontos de formatos; formats2D contém QR_CODE.
  • BarcodePicker.beep / BarcodePicker.vibrate (estáticos boolean) — feedback ao decodificar (default true).
  • String getAnswer() — último código decodificado, ou null se cancelado.
  • CameraBarcode.readBarcode(Image img) → com.google.zxing.Result (ou null) — decodifica de uma imagem estática. NÃO é thread-safe.

Divergência importante. BarcodePicker é abstract e usa o método onBarcode(...), não um callback do tipo RunnableWith. Instancie uma subclasse (anônima ou nomeada). O picker já emite beep()/vibrate(20) ao decodificar e suprime códigos repetidos (só chama onBarcode quando o texto muda). Ele não fecha sozinho ao ler — chame hide() dentro de onBarcode se quiser encerrar na primeira leitura. Toque no “X” (canto inferior direito) cancela.

Exemplo completo (copiar, colar e rodar)

package com.exemplo;

import com.google.zxing.*;                  // BarcodeFormat
import dev.crossfly.ui.*;                   // Window, Component, Button, Label
import dev.crossfly.ui.layout.*;            // VerticalLayout
import dev.crossfly.ui.picker.*;            // BarcodePicker

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

      Label resultado = new Label("");
      add(LAY_AUTO, resultado);

      Button acao = new Button("Ler QR Code");
      acao.onAction(c ->
      {
         // Leitura AO VIVO — só QR Code; fecha na primeira leitura
         BarcodePicker picker = new BarcodePicker("Aponte para o QR", BarcodePicker.formats2D)
         {
            protected void onBarcode(BarcodeFormat format, String code)
            {
               // Chamado FORA da paint thread → volte à UI com onUI(...)
               Component.onUI(() ->
               {
                  resultado.setText("Lido: " + code);
                  hide();            // encerra o scanner na primeira leitura (opcional)
               });
            }
         };
         picker.show();
      });
      add(LAY_AUTO, acao);
   }
}

O trecho abaixo mostra só o miolo. Para rodar, coloque-o no esqueleto MainWindow acima.

Trecho mínimo

// verificado na fonte: BarcodePicker.java (constructor, onBarcode, formats2D, getAnswer); CameraBarcode.java (readBarcode)
import com.google.zxing.*;                 // BarcodeFormat, Result
import dev.crossfly.ui.picker.*;           // BarcodePicker
import dev.crossfly.ui.*;                  // Component (onUI)

// 1) Leitura AO VIVO — só QR Code; fecha na primeira leitura
BarcodePicker picker = new BarcodePicker("Aponte para o QR", BarcodePicker.formats2D) {
   protected void onBarcode(BarcodeFormat format, String code) {
      // Chamado FORA da paint thread → volte à UI com onUI(...)
      Component.onUI(() -> {
         processar(code);   // ex.: preencher um campo, navegar, etc.
         hide();            // encerra o scanner na primeira leitura (opcional)
      });
   }
};
picker.show();             // deixe os formats vazios no construtor p/ aceitar todos os formatos

// 2) Decodificar de uma Image estática (uma câmera/thread por vez — não é thread-safe)
Result r = CameraBarcode.readBarcode(minhaImagem);
if (r != null) {
   String texto = r.getText();
   BarcodeFormat fmt = r.getBarcodeFormat();
}

Aprofunde-se

Esta página foi útil?