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 implementonBarcode(BarcodeFormat, String). Emptyformats= 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;formats2DcontainsQR_CODE.BarcodePicker.beep/BarcodePicker.vibrate(staticboolean) — feedback on decoding (defaulttrue).String getAnswer()— last decoded code, ornullif cancelled.CameraBarcode.readBarcode(Image img)→com.google.zxing.Result(ornull) — decodes from a static image. NOT thread-safe.
Important divergence.
BarcodePickerisabstractand uses theonBarcode(...)method, not aRunnableWith-type callback. Instantiate a subclass (anonymous or named). The picker already emitsbeep()/vibrate(20)on decoding and suppresses repeated codes (only callsonBarcodewhen the text changes). It does not close by itself when it reads — callhide()insideonBarcodeif 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
MainWindowskeleton 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
- Camera guide: Device camera · Widget: BarcodePicker
- Sibling recipe: tirar-foto.md