This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.
The paint thread
This is probably the most important rule of the framework for not corrupting your app.
CrossFly is single-threaded on the paint thread
Every UI and rendering operation happens on a single thread — the paint thread. Main
calls create(), render(), and resize() always on it; every onShow, onPaint, onLayout, touch callback,
and component change runs on it.
Why this decision? Simplicity and correctness. With a single thread of execution touching the UI, there are no locks, no contended shared state on the painting path. The price is a rule you must respect: never touch the UI from another thread.
The canonical pattern: heavy work off the thread, UI back with onUI
Network, database, file, long computation → background thread. To touch the UI with the result, go back
to the paint thread with Component.onUI(...):
new Thread(() -> {
List<Cliente> dados = repositorio.buscarTudo(); // heavy work, background thread
Component.onUI(() -> { // back to the paint thread
lista.setItems(dados); // now it's safe to touch the UI
Component.repaint(); // requests a new frame
});
}).start();
There is also Main.runOnPaintThread(Runnable) (and the variant runOnPaintThreadAndWait(...)) for the
same purpose outside the context of a Component.
Classic symptom of violating the rule: the app crashes or behaves erratically when “updating the screen” from inside a network/timer callback. The fix is always to wrap the UI touch with
onUI(...).
On-demand render
The paint thread does not keep redrawing continuously. A new frame is only generated when someone calls
repaint() (internally Gdx.graphics.requestRendering()). This saves battery — an idle screen
doesn’t consume GPU.
Most component setters already call repaint() for you. The consequences to remember:
- Changed something the framework doesn’t know about? Call
repaint()yourself. - Animation? It needs to keep the render request alive on each frame (this is what the animators do
in
onUpdate; see Value animations).
See also
- Related: The rendering pipeline · State and data flow
- Next: Layout and the Relative model