Tudo é um Component
Esta é a ideia que faz o resto do framework “clicar”. No CrossFly não há uma hierarquia de “widgets”
versus “containers”. Existe um tipo base — Component — e qualquer Component vira um
container no momento em que recebe um Layout.
container = Component + Layout
Component painel = new Component(); // um Component "vazio"
painel.setLayout(new VerticalLayout()); // agora ele organiza filhos → é um container
painel.add(LAY_AUTO, new Label("Título"));
painel.add(LAY_FILL, new ListView<>(...));
Um Button é um Component. Um Label é um Component. Uma Window (tela) é um Component de tela
cheia. Não existe uma classe Container especial — a “capacidade de conter” é só ter um Layout.
Isso significa que você compõe telas do mesmo jeito, sempre, do botão ao app inteiro.
Por que a classe base é desenhada assim
Component precisa escalar para milhares de instâncias sem explodir a memória. Duas decisões-chave:
- Bitfield (
cbits) em vez de dezenas deboolean. Estados como enabled, visible, focused, pressed, tem layout, tem estilo focado… são bits de um único inteiro long, não campos separados. Milhares de componentes × dezenas de flags booleanas seria desperdício; um bitfield resolve com um campo só. - Mapa de propriedades lazy (
property(k, v)). Coisas opcionais (callbacks, skin custom, imagem de fundo, estilos alternativos) não são campos fixos — vivem num mapa criado sob demanda. UmLabelsimples não paga por um campo de “imagem de fundo” que nunca vai usar.
// property(...) é o "saco de dados" idiomático para o que é opcional:
comp.property("meuFlag", true);
boolean f = comp.property("meuFlag"); // recupera (nulo se nunca setado)
Os estilos seguem a mesma filosofia: são criados sob demanda a partir do Skin, não instanciados
para todo componente na largada.
Hierarquia de pai único
Todo Component tem no máximo um pai. A árvore de composição é estritamente hierárquica: adicionar
um componente a um container o remove de qualquer pai anterior. Isso mantém o layout e a propagação de
eventos previsíveis (cada componente pertence a exatamente um lugar).
O que decorre disso
- Uma forma de compor tudo: aprender a montar um painel = saber montar uma tela.
- Layouts são plugáveis: o mesmo container muda de arranjo só trocando o
Layout(base da responsividade — ver Layout e o modelo Relative). - Custo baixo por componente: bitfield + propriedades lazy é o que torna listas grandes viáveis.
Veja também
- Aplicar: Layouts · Catálogo de componentes
- Próximo: O pipeline de renderização