Skip to content
CrossFly is 100% open sourceFollow us on GitHub
CrossFlyCrossFly
Get started

This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.

How to read a QR Code or barcode

Purpose. Open the camera and read a QR Code or barcode live with BarcodePicker, or decode a code from an already-captured Image with CameraBarcode.

APIs used

  • BarcodePicker(String title, BarcodeFormat... formats) — abstract live-reading window; you extend it and implement onBarcode(BarcodeFormat, String). Empty formats = accepts all.
  • abstract void onBarcode(BarcodeFormat format, String code) — called for each newly decoded code that passes the format filter.
  • BarcodePicker.formats1D / formats2D (static arrays) — ready-made format sets; formats2D contains QR_CODE.
  • BarcodePicker.beep / BarcodePicker.vibrate (static boolean) — feedback on decoding (default true).
  • String getAnswer() — last decoded code, or null if cancelled.
  • CameraBarcode.readBarcode(Image img) → com.google.zxing.Result (or null) — decodes from a static image. NOT thread-safe.

Important divergence. BarcodePicker is abstract and uses the onBarcode(...) method, not a RunnableWith-type callback. Instantiate a subclass (anonymous or named). The picker already emits beep()/vibrate(20) on decoding and suppresses repeated codes (only calls onBarcode when the text changes). It does not close by itself when it reads — call hide() inside onBarcode if you want to stop at the first read. Tapping the “X” (bottom-right corner) cancels.

Complete example (copy, paste, and run)

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

/** Runnable main screen. Point the launcher (classname) and run: 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 ->
      {
         // LIVE reading — QR Code only; closes on the first read
         BarcodePicker picker = new BarcodePicker("Aponte para o QR", BarcodePicker.formats2D)
         {
            protected void onBarcode(BarcodeFormat format, String code)
            {
               // Called OUTSIDE the paint thread → return to the UI with onUI(...)
               Component.onUI(() ->
               {
                  resultado.setText("Lido: " + code);
                  hide();            // closes the scanner on the first read (optional)
               });
            }
         };
         picker.show();
      });
      add(LAY_AUTO, acao);
   }
}

The snippet below shows only the core. To run it, place it in the MainWindow skeleton above.

Minimal snippet

// verified at source: 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) LIVE reading — QR Code only; closes on the first read
BarcodePicker picker = new BarcodePicker("Aponte para o QR", BarcodePicker.formats2D) {
   protected void onBarcode(BarcodeFormat format, String code) {
      // Called OUTSIDE the paint thread → return to the UI with onUI(...)
      Component.onUI(() -> {
         processar(code);   // e.g.: fill a field, navigate, etc.
         hide();            // closes the scanner on the first read (optional)
      });
   }
};
picker.show();             // leave the formats empty in the constructor to accept all formats

// 2) Decode from a static Image (one camera/thread at a time — not thread-safe)
Result r = CameraBarcode.readBarcode(minhaImagem);
if (r != null) {
   String texto = r.getText();
   BarcodeFormat fmt = r.getBarcodeFormat();
}

Go deeper

Was this page helpful?