This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.
BarcodePicker
BarcodePicker reads barcodes/QR codes from live camera frames, filtering by format. It is an abstract class: the consumer implements onBarcode(BarcodeFormat format, String code). It follows the picker pattern (see Picker) — it returns the read payload via getAnswer().
🔴 · Package:
dev.crossfly.ui.picker· Extends:Picker implements GdxCamera.Listener(abstract) · Hardware: camera
ℹ️ This
BarcodePickeris the camera-based reader and still exists. Do not confuse it with the old barcode generation utility (util/barcode), which was removed during modernization.
When to use
- Scan barcodes (products, tickets) or QR codes.
When NOT to use
- Take a photo/record video → use
PhotoPicker.
Appearance
Full-screen camera preview (black background), title at the top, a central red crosshair for aiming, and a white “X” close button in the bottom-right corner.
Complete example (copy, paste and run)
BarcodePicker is abstract: instantiate it with a body implementing onBarcode. Since it is a camera overlay, trigger it from a Button. The example reuses the basic usage (1D formats, closes on the 1st read) and writes the payload into a Label. BarcodeFormat comes from com.google.zxing.
package com.exemplo;
import com.google.zxing.BarcodeFormat;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.picker.*;
/** 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 saida = new Label("Nenhum código lido");
add(LAY_AUTO, saida);
Button escanear = new Button("Escanear código")
.onAction(c ->
{
BarcodePicker scanner = new BarcodePicker("Aponte para o código", BarcodePicker.formats1D)
{
protected void onBarcode(BarcodeFormat format, String code)
{
onUI(() -> saida.setText(format + ": " + code)); // back to the paint thread
hide(); // closes after the 1st read (doesn't close on its own)
}
};
scanner.show(answer -> {});
});
add(LAY_AUTO, escanear);
}
}
The snippets below show only the core (what goes inside
onShow()). To run them, place them in theMainWindowskeleton above.
Basic usage
BarcodePicker scanner = new BarcodePicker("Aponte para o código", BarcodePicker.formats1D)
{
protected void onBarcode(BarcodeFormat format, String code)
{
Debug.log(format + ": " + code);
hide(); // closes after the 1st read
}
};
scanner.show(answer -> campoCodigo.setText((String) answer));
Constructors
| Constructor | Description |
|---|---|
BarcodePicker(String title, BarcodeFormat... formats) |
Title + accepted formats (varargs; empty = all). Abstract — instantiate with a body implementing onBarcode. |
Properties and customization
| Member | Type | Default | What it does |
|---|---|---|---|
BarcodePicker.formats1D (static) |
BarcodeFormat[] |
— | Ready-made set of 1D formats (CODE_128, EAN_13…). |
BarcodePicker.formats2D (static) |
BarcodeFormat[] |
— | Ready-made set of 2D formats (QR_CODE). |
BarcodePicker.beep (static) |
boolean |
true |
Beeps on decoding. |
BarcodePicker.vibrate (static) |
boolean |
true |
Vibrates on decoding. |
Callbacks and events
| Callback | When it fires |
|---|---|
onBarcode(BarcodeFormat, String) |
(abstract) on decoding a code of an accepted format. |
show(onAnswer) |
on close, delivers the String of the last read payload. |
getAnswer() returns the last decoded payload, or null if canceled.
States
- There is no automatic
hide()on detection — you decide when to close in youronBarcode(by callinghide()). Without it, the scanner keeps reading (useful for continuous reading). - Consecutive repeated codes (same
lastCode) are ignored. onAppPause/onAppResumemanage the camera;onRemovestops the decoding thread.
Accept only QR and close on the first read
BarcodePicker scanner = new BarcodePicker("Leia o QR", BarcodePicker.formats2D)
{
protected void onBarcode(BarcodeFormat format, String code)
{
onUI(() -> campoCodigo.setText(code)); // UI update on the paint thread
hide();
}
};
scanner.show(answer -> Debug.log("Lido: " + answer));
Best practices
- Call
hide()inonBarcodefor a single read; omit it for continuous reading. - Decoding runs on a background thread — wrap UI updates in
onUI(...).
Common mistakes
- Forgetting
hide()when you wanted a single read — the scanner stays active. - Updating the UI directly in
onBarcode— respect the paint thread withonUI(...).
See also
- Area guide:
ui/· Recipes:cookbook/ - Pattern base:
Picker - Related components:
PhotoPicker