This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.
Skins
A Skin defines the structural visual identity of all components: shape (corners), border thickness,
spacing, shadows and default icons. There are three built in: MaterialSkin, IOSSkin
and FlutterSkin.
Skin ≠ colors. Skin = structure/renderer; the palette (light/dark, primary/surface…) comes from the
ColorScheme/ThemeMode. A custom skin changes shape/spacing, not color.
Default skin
Skin.get() returns MaterialSkin by default — or IOSSkin automatically on iOS.
Complete example (copy, paste and run)
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*; // Styles
import dev.crossfly.ui.skin.*; // Skin, MaterialSkin, IOSSkin, FlutterSkin
/** 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();
Skin.set(new IOSSkin()); // global skin = iOS structure/shape (colors still come from the theme)
setLayout(new VerticalLayout());
// Buttons to switch the global skin in real time:
Button material = new Button("Skin Material");
material.onAction(c -> { Skin.set(new MaterialSkin()); restyle(); });
add(LAY_AUTO, material);
Button ios = new Button("Skin iOS");
ios.onAction(c -> { Skin.set(new IOSSkin()); restyle(); });
add(LAY_AUTO, ios);
Button flutter = new Button("Skin Flutter");
flutter.onAction(c -> { Skin.set(new FlutterSkin()); restyle(); });
add(LAY_AUTO, flutter);
// Skin per component: this button stays iOS even if the global one changes.
Button fixoIos = new Button("Sempre iOS");
fixoIos.skin(new IOSSkin());
add(LAY_AUTO, fixoIos);
}
}
The snippets below show only the core (what goes inside
onShow()). To run them, place them in theMainWindowskeleton above.
Switch the global skin
Affects all components that do not have their own skin:
Skin.set(new IOSSkin()); // the whole UI gets the iOS look
Skin.set(new FlutterSkin()); // … or Flutter
Skin per component
Overrides the global one only in that component:
meuBotao.skin(new IOSSkin()); // this button stays iOS, the rest remains Material
Custom skin (change shape/spacing, not color)
Extend a skin and override the structure hooks:
public class RoundedSkin extends MaterialSkin {
@Override public float borderRadius() { return 1.5f; } // nicely rounded corners
@Override public float borderThick() { return 0.05f; } // thin border
}
// apply globally:
Skin.set(new RoundedSkin());
To adapt colors to light/dark, do not touch the skin — use ColorScheme/ThemeMode
(see Light/dark mode).
How the layers interact
Best practices
- Choose one global skin at bootstrap; use
.skin(...)per component only for exceptions. - Custom skin = shape/spacing/shadow. Color and light/dark =
ColorScheme.
Common mistakes
- Trying to change colors by overriding the skin — colors come from
ColorScheme, not the skin. - Mixing different skins on the same screen without need (visual inconsistency).