This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.
Responsiveness in every layout
CrossFly uses logical pixels and recomputes the layout on rotation/resize. If you follow the principles below, the screen re-adapts on its own — with no resize code.
This is the practical summary. The complete guide, with an example in each layout and an end-to-end screen example, is Chapter 36 — Layout and Responsiveness Best Practices.
The 5 principles
- Never position in fixed pixels. Use fractions,
RelativeandLAY_FILL/LAY_AUTO/RelSize.FILL. - Let the layout measure.
LAY_AUTO,RelSize.AUTOSIZEandRelative.AUTOreport the natural size. - Spacing scales too. Padding (
ingap) and margin (outgap) viaGap.ofFont(...)/Gap.ofScreen(...). - One “elastic” area. Mark one component with
LAY_FILL(Vertical/Horizontal) to absorb the remainder. - Resize is automatic — if you used the items above. Only manual positioning (
setBounds) requires code.
The central tool: Relative
| Form | Result |
|---|---|
Relative.ofFont(1.5f) |
1.5 × font height (scales with the font/DPI) |
Relative.ofScreen(0.8f) |
80% of the screen dimension |
Relative.ofScreen(0.5f, ScreenSize.MIN) |
50% of the smaller side (adapts to portrait/landscape) |
Relative.FULL / AUTO / CENTER |
fills the parent / content size / centers |
Full example (copy, paste and run)
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
/** Runnable main screen. Point the launcher (classname) and run: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
private Component painel; // rearranged on each resize/rotation
private Component lista;
private Component detalhe;
@Override
public void onShow() throws Exception
{
super.onShow();
lista = new Label("Lista");
detalhe = new Label("Detalhe");
painel = new Component();
setLayout(new VerticalLayout(Position.START, Position.START));
add(LAY_FILL, painel);
// onReposition() is called on the first layout and on each resize/rotation:
// it chooses the panel arrangement according to the orientation.
}
@Override
protected void onReposition() throws Exception
{
painel.removeAll();
if (Screen.isLandscape) {
painel.setLayout(new HorizontalLayout());
painel.add(0.5f, lista); painel.add(0.5f, detalhe);
} else {
painel.setLayout(new VerticalLayout());
painel.add(LAY_FILL, lista); painel.add(LAY_AUTO, detalhe);
}
}
}
The snippets below show only the core (what goes inside
onShow()). To run them, place them in theMainWindowskeleton above.
When the arrangement should CHANGE by orientation
Override Window.onReposition() (called before the relayout) and re-pick the layout:
@Override protected void onReposition() throws Exception {
painel.removeAll();
if (Screen.isLandscape) {
painel.setLayout(new HorizontalLayout());
painel.add(0.5f, lista); painel.add(0.5f, detalhe);
} else {
painel.setLayout(new VerticalLayout());
painel.add(LAY_FILL, lista); painel.add(LAY_AUTO, detalhe);
}
}
Breakpoints: use Screen.minSize (the smaller side is stable across orientations), e.g.: tablet = Screen.minSize >= 600.
See also
- Layout catalog · Primitives:
Relative/Gap