Pular para o conteúdo
CrossFly é 100% open sourceSiga no GitHub
CrossFlyCrossFly
Começar

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 de boolean. 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. Um Label simples 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

Esta página foi útil?