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.

5. Styling and themes

What you’ll learn: giving things a look without hardcoding values and switching light/dark live. Prerequisites: Layouts.

Complete example (copy, paste, and run)

Sets the app theme (seed + skin), styles a button per state, and adds a button that switches light↔dark live — the whole UI follows without manual restyling. Compiles as is.

package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;
import dev.crossfly.ui.skin.*;

public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // theme: one seed generates the full scheme; the skin defines the shape
      Styles.setColorScheme(0xFF6750A4, ThemeMode.LIGHT);
      Skin.set(new IOSSkin());

      Button botao = new Button("Salvar");
      botao.style(new ComponentStyle()
         .backColor(Styles.primaryColor)   // theme's PalColor (follows light/dark)
         .textColor(0xFFFFFFFF)            // fixed int ARGB 0xAARRGGBB
         .borderRadius(0.6f)
         .pressable());                    // enables press feedback
      add(LAY_AUTO, botao);

      Button botaoTema = new Button("Alternar claro/escuro");
      botaoTema.onAction(c -> Styles.toggleDarkMode());   // re-skins the whole UI by itself
      add(LAY_AUTO, botaoTema);
   }
}

The snippets below show only the core (what goes inside onShow()). To run them, put them in the MainWindow skeleton above.

ComponentStyle and per-state styles

Every component can have three styles, chosen per frame: default / focused / pressed.

botao.style(new ComponentStyle()
   .backColor(Styles.primaryColor)     // theme's PalColor (follows light/dark)
   .textColor(0xFFFFFFFF)              // or fixed int ARGB 0xAARRGGBB
   .borderRadius(0.6f)
   .pressable());                      // enables press feedback

Skin and color scheme

The Skin defines the shape (Material/iOS/Flutter); the ColorScheme defines the palette from a seed color:

Styles.setColorScheme(0xFF6750A4, ThemeMode.LIGHT);   // one seed → full scheme
Skin.set(new IOSSkin());                               // changes the global visual identity

Switching light↔dark at runtime (without recreating the UI)

setDarkMode(...) re-applies the theme to all windows automatically — if your styles use the theme’s PalColor (Styles.primaryColor, etc.), the colors change on their own:

Button botaoTema = new Button("Modo escuro");
botaoTema.onAction(c -> Styles.toggleDarkMode());   // the whole UI follows, without manual restyle

For styles that change shape per mode, register them with styled(...) (see Light/dark mode).

What you build in this step

The app theme (seed + skin) + a button that switches light/dark live.

Recap

ComponentStyle (default/focused/pressed); ARGB colors or the theme’s PalColor; Skin = shape, ColorScheme = palette; toggleDarkMode() re-dresses everything on its own.

Next steps

→ Handling input

See also

Was this page helpful?