Saltar al contenido
CrossFly es 100% open sourceSíguenos en GitHub
CrossFlyCrossFly
Empezar

Esta página fue traducida automáticamente del portugués y puede contener errores. La versión en portugués es la canónica.

Cómo leer un QR Code o código de barras

Propósito. Abrir la cámara y leer un QR Code o código de barras en vivo con el BarcodePicker, o decodificar un código a partir de una Image ya capturada con CameraBarcode.

APIs usadas

  • BarcodePicker(String title, BarcodeFormat... formats) — ventana abstracta de lectura en vivo; tú la extiendes e implementas onBarcode(BarcodeFormat, String). formats vacío = acepta todos.
  • abstract void onBarcode(BarcodeFormat format, String code) — llamado por cada código nuevo decodificado que pasa el filtro de formatos.
  • BarcodePicker.formats1D / formats2D (arrays estáticos) — conjuntos listos de formatos; formats2D contiene QR_CODE.
  • BarcodePicker.beep / BarcodePicker.vibrate (estáticos boolean) — feedback al decodificar (default true).
  • String getAnswer() — último código decodificado, o null si se canceló.
  • CameraBarcode.readBarcode(Image img) → com.google.zxing.Result (o null) — decodifica desde una imagen estática. NO es thread-safe.

Divergencia importante. BarcodePicker es abstract y usa el método onBarcode(...), no un callback del tipo RunnableWith. Instancia una subclase (anónima o nombrada). El picker ya emite beep()/vibrate(20) al decodificar y suprime códigos repetidos (solo llama a onBarcode cuando el texto cambia). No se cierra solo al leer — llama a hide() dentro de onBarcode si quieres terminar en la primera lectura. Tocar la “X” (esquina inferior derecha) cancela.

Ejemplo completo (copiar, pegar y ejecutar)

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

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: 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 ->
      {
         // Lectura EN VIVO — solo QR Code; cierra en la primera lectura
         BarcodePicker picker = new BarcodePicker("Aponte para o QR", BarcodePicker.formats2D)
         {
            protected void onBarcode(BarcodeFormat format, String code)
            {
               // Llamado FUERA de la paint thread → vuelve a la UI con onUI(...)
               Component.onUI(() ->
               {
                  resultado.setText("Lido: " + code);
                  hide();            // cierra el scanner en la primera lectura (opcional)
               });
            }
         };
         picker.show();
      });
      add(LAY_AUTO, acao);
   }
}

El fragmento de abajo muestra solo el núcleo. Para ejecutarlo, colócalo en el esqueleto MainWindow de arriba.

Fragmento mínimo

// verificado en la fuente: 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) Lectura EN VIVO — solo QR Code; cierra en la primera lectura
BarcodePicker picker = new BarcodePicker("Aponte para o QR", BarcodePicker.formats2D) {
   protected void onBarcode(BarcodeFormat format, String code) {
      // Llamado FUERA de la paint thread → vuelve a la UI con onUI(...)
      Component.onUI(() -> {
         processar(code);   // ej.: rellenar un campo, navegar, etc.
         hide();            // cierra el scanner en la primera lectura (opcional)
      });
   }
};
picker.show();             // deja los formats vacíos en el constructor p/ aceptar todos los formatos

// 2) Decodificar de una Image estática (una cámara/thread a la vez — no es thread-safe)
Result r = CameraBarcode.readBarcode(minhaImagem);
if (r != null) {
   String texto = r.getText();
   BarcodeFormat fmt = r.getBarcodeFormat();
}

Profundiza

¿Te resultó útil esta página?