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.

Quickstart: Hello World

The “it works!” moment. By the end of this page you’ll have an interactive app running on the desktop.

Complete example (copy, paste and run)

Create your main window — a subclass of dev.crossfly.ui.Window:

package com.exemplo.app;

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

public class MainWindow extends Window {
   @Override
   public void onShow() throws Exception {
      super.onShow();                       // required: valid bounds + fires onAdd
      setLayout(new VerticalLayout());

      Label saudacao = new Label("Olá, CrossFly!");
      Button botao = new Button("Clique");
      botao.onAction(c -> saudacao.setText("Você clicou!"));   // runs on the paint thread

      add(LAY_AUTO, saudacao);              // LAY_AUTO = natural height
      add(LAY_AUTO, botao);
   }
}

Run

gradlew :lwjgl3:run

A window opens with the text and the button; clicking swaps the text. 🎉

The 4 facts that hold up everything else

  1. A screen = a subclass of Window. Each screen of the app is a Window.
  2. The UI is built in onShow(), not in the constructor (there the bounds aren’t valid yet) — and always with super.onShow().
  3. Everything is a Component and add(size, comp) delegates the arrangement to the Layout (LAY_AUTO=natural, LAY_FILL=fills the remaining space).
  4. The MainWindow is referenced by classname (see Anatomy of a project).

No reactive binding: the click mutates the Label (setText) — you update the UI by hand. It’s the imperative model of CrossFly (see State and data flow).

Next steps

→ Your first app (guided, end to end)

See also

Was this page helpful?