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.

Color schemes (ColorScheme)

A ColorScheme is a semantic palette inspired by Material 3: from a single seed color, the framework generates all the coherent colors (primary, surface, error, outline…) for light and dark.

Complete example (copy, paste and run)

package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;   // Styles, ComponentStyle, ThemeMode
import dev.crossfly.ui.color.*;   // ColorScheme

/** Runnable main screen. Point the launcher (classname) and run: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();

      // entire palette from a seed color (Material 3), dark mode
      Styles.setColorScheme(0xFF6750A4, ThemeMode.DARK);

      setLayout(new VerticalLayout());

      // reads the global palette and styles a card by semantic ROLES
      ColorScheme cs = Styles.colorScheme();
      Label card = new Label("Cartão temático");
      card.style(new ComponentStyle()
         .backColor(cs.surface)             // theme background
         .textColor(cs.onSurface)           // theme text
         .borderColor(cs.outline.color())   // subtle border (int ARGB)
         .borderRadius(0.6f)
         .ingap(Gap.ofFont(0.8f)));
      add(LAY_AUTO, card);

      Button primario = new Button("Ação principal");
      primario.style(Styles.button()
         .backColor(cs.primary)             // primary role → main button
         .textColor(cs.onPrimary));
      add(LAY_AUTO, primario);
   }
}

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

Apply it in one line

// entire palette from a seed (light)
Styles.setColorScheme(0xFF0173ED);

// same identity, dark mode
Styles.setColorScheme(0xFF6750A4, ThemeMode.DARK);

After that, all components created via Skin use that palette automatically.

Ways to create a ColorScheme

ColorScheme.fromSeed(0xFF6750A4);              // 1 seed → light palette
ColorScheme.fromSeed(0xFF6750A4, true);        // 1 seed → dark palette
ColorScheme.light(0xFF0066CC, 0xFF00AA44, 0xFFFF9900); // 3 brand colors (primary/secondary/tertiary)
ColorScheme.materialPurple(false);             // ready-made presets
ColorScheme.iosBlue(false); ColorScheme.flutterTeal(false);
ColorScheme.forestGreen(false); ColorScheme.deepOrange(false); ColorScheme.oceanBlue(false);

Semantic roles (use by intent, not by color)

Role Use in
primary / onPrimary primary buttons, active indicators / text on top of them
primaryContainer / onPrimaryContainer selected cards, active chips
secondary / tertiary secondary actions / highlights
surface / onSurface screen and card background / primary text
surfaceVariant / onSurfaceVariant subtle background / subtitles, hints, disabled
outline / outlineVariant borders, dividers / subtle borders
error / onError validation, destructive actions / text on error
ColorScheme cs = Styles.colorScheme();
card.style(new ComponentStyle()
   .backColor(cs.surface)          // theme background
   .textColor(cs.onSurface)        // theme text
   .borderColor(cs.outline.color()));

Switch a palette’s variant

ColorScheme claro = ColorScheme.fromSeed(0xFF6750A4);
ColorScheme escuro = claro.toDark();        // same identity, dark tones
ColorScheme oposto = claro.toggleDarkLight();

Best practices

  • Set the seed once at bootstrap; on screens, use the roles (cs.primary, cs.surface).
  • Choose the color by intent (error for destructive), not by RGB value.
  • During static initialization, prefer setColorSchemeSilent(...) (does not trigger a reset).

Common mistakes

  • Spreading fixed 0xFF... values across the UI instead of using the ColorScheme roles (breaks dark mode).
  • Recreating the ColorScheme on every screen — it is global; read it with Styles.colorScheme().

See also

Was this page helpful?