Skip to content
CrossFly is 100% open sourceFollow us on GitHub
CrossFlyCrossFly
Get started
All examples
RecipesLayout93 lines · 1 files

Layouts

Any Component becomes a container with setLayout. The same three labels, three ways.

What this shows

The three layouts you will use for almost everything, and what each does with the same content.

One thing worth knowing before you copy this: the multi-child form of add - several weights and several components in one call - belongs to GridLayout alone. Vertical and horizontal layouts take one child per call and throw a UIException otherwise, at show time rather than at compile time.

Run it on your machine

Every example is a plain Window, so the launcher only needs its name.

gradlew lwjgl3:run --args="classname dev.cf.recipe.R01Layouts"
Editing it

Java is compiled ahead of time, so the browser cannot rebuild an edit on its own — the code you see here was turned into JavaScript by TeaVM before it was published. Copy the file into a project and it runs unchanged on all four platforms; the command above is the whole setup.

Running hereCrossFly 0.1.32
Starting the app…

Compiled to WebAssembly-era JavaScript by TeaVM — the same code, not a video of it. · All examples

What it uses

Framework types this example touches. The linked ones have a reference page.

CardComponentGapGridLayoutHorizontalLayoutLabelLayoutPalColorVerticalLayoutWidgets

The source

Complete and unabridged. This is the file, not an excerpt of it.

Raw
dev/cf/recipe/R01Layouts.java
package dev.cf.recipe;

import dev.cf.Tones;

import dev.crossfly.ui.*;
import dev.crossfly.ui.color.*;
import dev.crossfly.ui.graphics.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;

import static dev.crossfly.ui.Widgets.*;

/**
 * The three layouts you will use for almost everything, and what each does with the same content.
 *
 * <p>One thing worth knowing before you copy this: the multi-child form of {@code add} - several
 * weights and several components in one call - belongs to {@link GridLayout} alone. Vertical and
 * horizontal layouts take one child per call and throw a {@code UIException} otherwise, at show
 * time rather than at compile time.</p>
 */
public class R01Layouts extends Recipe
{
   private static final int IC_STACK = 0xE949, IC_ROW = 0xE947, IC_GRID = 0xE871;

   public String title()
   {
      return "Layouts";
   }

   public String note()
   {
      return "Any Component becomes a container with setLayout. The same three labels, three ways.";
   }

   public void build(Component body) throws Exception
   {
      // Each layout gets its own tone, and the three chips inside it are drawn in that tone. The
      // colour is doing the explaining: the same three chips appear three times, and what changed
      // between the panels is only where the layout put them.
      body.add(LAY_AUTO, caixa(IC_STACK, "VerticalLayout — stacked", Tones.accent(),
         new VerticalLayout(Position.START, Position.START)));

      // HorizontalLayout: side by side. The container is as wide as the SUM.
      body.add(LAY_AUTO, caixa(IC_ROW, "HorizontalLayout — in a row", Tones.support(),
         new HorizontalLayout(Position.START, Position.CENTER)));

      // GridLayout: you declare the column weights in add(). 1f is "take what is left".
      Component grade = new Component();
      grade.setLayout(new GridLayout(Position.START, Position.CENTER));
      grade.add(.25f, .5f, .25f, texto("25%", Tones.highlight()), texto("50%", Tones.highlight()),
         texto("25%", Tones.highlight()));
      body.add(LAY_AUTO, rotulado(IC_GRID, "GridLayout — declared weights", Tones.highlight(),
         grade));
   }

   /** Three chips under the given layout, inside a panel of that layout's tone. */
   private Component caixa(int icone, String rotulo, PalColor tom, Layout l) throws Exception
   {
      Component c = new Component();
      c.setLayout(l);
      // One child per call: the form with several weights at once belongs to GridLayout, and only to it.
      c.add(LAY_AUTO, texto("one", tom));
      c.add(LAY_AUTO, texto("two", tom));
      c.add(LAY_AUTO, texto("three", tom));
      return rotulado(icone, rotulo, tom, c);
   }

   private Component rotulado(int icone, String rotulo, PalColor tom, Component alvo)
      throws Exception
   {
      Card fora = Tones.card(tom);
      fora.setLayout(new VerticalLayout(Position.START, Position.START));
      fora.getStyle()
         .outgap(Gap.ofFont(0, 0, 0, .7f));
      fora.add(LAY_AUTO, Tones.head(icone, rotulo, tom));
      fora.add(LAY_AUTO, alvo);
      return fora;
   }

   /**
    * One item, in its panel's tone.
    *
    * <p>A plain toned label rather than a pill: a Badge added to a VerticalLayout is handed the
    * container's width, and forcing it to hug squeezed the text down to an unreadable smear. The
    * panel already carries the tone — the item only has to be legible and left-aligned, so that
    * WHERE the layout put it is the only thing that changes between the three panels.</p>
    */
   private Label texto(String t, PalColor tom)
   {
      return outgap(label(t, 1.1f, true, tom, Position.START), 0, .1f, .9f, .1f);
   }
}
For an AI assistant

Machine-readable versions of this page, so a model can read the shelf instead of guessing at the API.

This example, as JSONThis example, as Markdown
NextTheme tokens