Skip to content
CrossFly is 100% open sourceFollow us on GitHub
CrossFlyCrossFly
Get started

This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.

Everything is a Component

This is the idea that makes the rest of the framework “click”. In CrossFly there is no hierarchy of “widgets” versus “containers”. There is one base type — Component — and any Component becomes a container the moment it receives a Layout.

container = Component + Layout

Component painel = new Component();       // an "empty" Component
painel.setLayout(new VerticalLayout());   // now it arranges children → it's a container
painel.add(LAY_AUTO, new Label("Título"));
painel.add(LAY_FILL, new ListView<>(...));

A Button is a Component. A Label is a Component. A Window (screen) is a full-screen Component. There is no special Container class — the “ability to contain” is just having a Layout. This means you compose screens the same way, always, from a button to an entire app.

Why the base class is designed this way

Component needs to scale to thousands of instances without blowing up memory. Two key decisions:

  • Bitfield (cbits) instead of dozens of booleans. States like enabled, visible, focused, pressed, has layout, has focused style… are bits of a single long integer, not separate fields. Thousands of components × dozens of boolean flags would be wasteful; a bitfield solves it with a single field.
  • Lazy property map (property(k, v)). Optional things (callbacks, custom skin, background image, alternate styles) are not fixed fields — they live in a map created on demand. A simple Label doesn’t pay for a “background image” field it will never use.
// property(...) is the idiomatic "data bag" for what is optional:
comp.property("meuFlag", true);
boolean f = comp.property("meuFlag");   // retrieves (null if never set)

The styles follow the same philosophy: they are created on demand from the Skin, not instantiated for every component up front.

Single-parent hierarchy

Every Component has at most one parent. The composition tree is strictly hierarchical: adding a component to a container removes it from any previous parent. This keeps layout and event propagation predictable (each component belongs to exactly one place).

What follows from this

  • One way to compose everything: learning to build a panel = knowing how to build a screen.
  • Layouts are pluggable: the same container changes its arrangement just by swapping the Layout (the basis of responsiveness — see Layout and the Relative model).
  • Low cost per component: bitfield + lazy properties is what makes large lists viable.

See also

Was this page helpful?