This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.
How to take a photo and get the file path
Purpose. Open the camera, take a photo, and receive the file path of the recorded JPEG.
The recommended approach is to use Camera with cameraType = CameraType.PICKER, which under the hood opens the
PhotoPicker (the framework’s own capture UI) and returns the path — or null if cancelled.
APIs used
Camera— no-argument constructor; public fieldscameraType(CameraType),captureMode(Preview, defaultPHOTO),videoQuality(AVQuality),videoTimeLimit.Camera.shot()→String— takes the photo/video according to the fields and returns the file path ornull(cancelled, error, or macOS ARM). There is noclick()method.CameraType(enum) —DEFAULT(OS native camera),PICKER(CrossFly UI viaPhotoPicker),GALLERY(pick from the gallery).PhotoPicker(Preview type)— used internally byshot()whencameraType == PICKER; exposesgetAnswer()(path or error string) andisError().Camera.shot()already converts an error intonullfor you.
Divergence/honesty note.
PhotoPickeris not abstract and does not use anonAnswercallback: it stores the result ingetAnswer()and signals failure viaisError().Camera.shot()wraps this flow (show()→ readsgetAnswer()→isError() ? null : ret), so prefershot(). On iOS, whencaptureMode != PHOTO,shot()delegates directly to the OS native camera.
Complete example (copy, paste and run)
package com.exemplo;
import dev.crossfly.ui.*; // Window, Component, Button, Label, UIConstants
import dev.crossfly.ui.layout.*; // VerticalLayout
import dev.crossfly.device.*; // Camera
/** 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("Tirar foto");
acao.onAction(c ->
{
// shot() is blocking while the picker is open; run it outside the paint thread.
new Thread(() ->
{
Camera cam = new Camera();
cam.cameraType = UIConstants.CameraType.PICKER; // CrossFly capture UI
cam.captureMode = UIConstants.Preview.PHOTO; // photo (default)
String path = cam.shot(); // path of the JPEG, or null if cancelled/error
// The return arrives OUTSIDE the paint thread → return to the UI with onUI(...)
Component.onUI(() ->
resultado.setText(path != null ? "Foto: " + path : "Cancelado ou erro"));
}).start();
});
add(LAY_AUTO, acao);
}
}
The snippet below shows only the core. To run it, place it inside the
MainWindowskeleton above.
Minimal snippet
// verified at source: Camera.java shot() (lines 75-91); PhotoPicker.java (constructor + getAnswer/isError)
import dev.crossfly.device.*; // Camera
import dev.crossfly.ui.*; // Component (onUI), UIConstants.CameraType/Preview
// shot() is blocking while the picker is open; run it outside the paint thread.
new Thread(() -> {
Camera cam = new Camera();
cam.cameraType = UIConstants.CameraType.PICKER; // CrossFly capture UI
cam.captureMode = UIConstants.Preview.PHOTO; // photo (default)
String path = cam.shot(); // path of the JPEG, or null if cancelled/error
// The return arrives OUTSIDE the paint thread → return to the UI with onUI(...)
Component.onUI(() -> {
if (path != null)
mostrarFoto(path); // e.g.: load the Image and show it in an ImageView
// else: user cancelled or there was a camera error
});
}).start();
Dive deeper
- Camera guide: Device camera · Widget: PhotoPicker
- Sibling recipe: gravar-video.md · ler-codigo-de-barras.md