Lekce 2 - FXML a první formulářová aplikace v JavaFX
V předchozí lekci, Úvod do JavaFX, jsme si JavaFX představili a nainstalovali.
V dnešním JavaFX tutoriálu si podrobněji rozebereme ukázkovou aplikaci z
minulého dílu. Posléze ji předěláme na klasickou Hello world
aplikaci.
FXML a formulářové prvky
V JavaFX je možné, podobně jako ve starším Swingu, tvořit instance jednotlivých formulářových prvků (tlačítko, textové pole) přímo v kódu. Ty poté vkládáme do tzv. layoutů, což jsou vlastně kontejnery na formulářové komponenty.
Můžeme ale také definovat uživatelské rozhraní ve FXML. Tento druhý způsob si ukážeme a budeme ho využívat.
FXML je jazyk pro návrh formulářů. Asi vás podle názvu nepřekvapí, že je to další jazyk odvozený z XML. Použití XML pro návrh prezentační části aplikace (to je ta část, se kterou komunikuje uživatel) není nic nového, naopak se jedná o osvědčený princip z webových aplikací. Java se zde, stejně jako C#, inspiruje a přenáší principy HTML a CSS do desktopových aplikací.
Dobrou zprávou je, že FXML nemusíme psát ručně, máme totiž k dispozici grafický designer Scene Builder, který jsme si nainstalovali v minulé lekci.
Původní aplikace HelloFX
Pojďme ale nejprve prozkoumat blíže aplikaci, kterou jsme vytvořili v
minulé lekci. Poté, co si ji důkladně rozebereme, ji upravíme na klasickou
Hello World aplikaci.
V NetBeans si otevřeme náš projekt HelloFx z minulé lekce.
Ten obsahuje tři Java soubory ve složce Source Packages v
balíčku cz.itnetwork.hellofx. Další dva soubory -
primary.fxml a secondary.fxml najdeme, když
rozklikneme složku Other Packages a proklikáme se až ke
stejnojmennému balíčku. Všechny si nyní popíšeme.
Soubory .fxml
Soubory primary.fxml a secondary.fxml obsahují
FXML kód, který popisuje, jak formulář vypadá. Pokud máme
nainstalovaný Scene Builder a na některý z těchto souborů
v okně Projects 2x klikneme, otevře se formulář právě v tomto
nástroji:

Jestliže jste Scene Builder instalovali, když byly NetBeans spuštěné, musíte je nejprve restartovat!
V prostředním sloupci okna vidíme, jak formulář vypadá. V levé části
se nachází Library, to je paleta komponent, které na formulář
můžeme přesouvat. Pod ní, v okně Hierarchy, vidíme stromovou
strukturu komponent, které jsou na formuláři vložené. V našem případě
se jedná o Button (tlačítko) a Label (textový
popisek) umístěné v layoutu VBox. V pravém sloupci,
Inspector, vidíme vlastnosti označené komponenty.
Zkusme si v prostředním sloupci kliknout na Button a v
záložce Properties se objeví např. text tlačítka:

Záložky Layout si zatím nebudeme všímat a přesuneme se do
záložky Code. Ta je velmi důležitá. Pokud nějakou komponentu
chceme používat v Java kódu, musíme jí přidělit
fx:id. To je název proměnné, přes kterou ke komponentě budeme
přistupovat. Vidíme, že tlačítko má fx:id nastavené na
primaryButton. Níže vidíme také přiřazení událostí,
konkrétně událost On Action zavolá metodu
switchToSecondary():

Kód .fxml souboru
Vrátíme se do NetBeans a na soubor primary.fxml tentokrát
klikneme pravým tlačítkem a zvolíme Edit. NetBeans nám otevře
přímo obsah dokumentu, který vypadá takto:
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.layout.VBox?> <?import javafx.scene.control.Label?> <?import javafx.scene.control.Button?> <?import javafx.geometry.Insets?> <VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cz.itnetwork.hellofx.PrimaryController"> <children> <Label text="Primary View" /> <Button fx:id="primaryButton" text="Switch to Secondary View" onAction="#switchToSecondary"/> </children> <padding> <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" /> </padding> </VBox>
Tento kód nám Scene Builder generuje sám podle toho, co v něm naklikáme. Ručně do něj nebudeme zasahovat. Přesto si ho popíšeme, abychom chápali, jak technologie funguje.
Vidíme zde XML hlavičku, dále nějaké importy balíčků s komponentami a
poté VBox, což je layout okna aplikace. Ten má pomocí atributu
fx:controller nastavený Java kontroler, ke kterému se hned
vrátíme. VBox má v sobě element children a v něm
vložené další komponenty. V našem případě je to Button a
Label. Vidíme, že atributy opravdu souhlasí s tím, co jsme
viděli v Scene Builderu.
Kontroler
PrimaryController.java
Kontroler obsahuje Java kód, kterým formulář obsluhujeme. V našem případě vypadá takto:
package cz.itnetwork.hellofx; import java.io.IOException; import javafx.fxml.FXML; public class PrimaryController { @FXML private void switchToSecondary() throws IOException { App.setRoot("secondary"); } }
Kontroler obsluhuje formulář, umožňuje měnit vlastnosti komponent a
reagovat na jejich události. Všimněme si anotace @FXML u metody
switchToSecondary(). Takto označujeme metody, ale i proměnné,
které chceme použít ve FXML. Určitě si vybavíme, že
právě tuto metodu jsme viděli ve Scene Builderu u
tlačítka.
Soubor App.java
Soubor App.java je pomyslnou vstupní branou do aplikace.
Obsahuje metodu main(), která se - jako v jakékoliv jiné Java
aplikaci - spouští jako úplně první. My v ní pouze voláme metodu
launch(), čímž se řízení předá JavaFX.
Všimněme si, že třída App dědí od třídy
Application, čímž dostáváme k dispozici nejen metodu
launch(), ale i metodu start(), ve které můžeme
definovat, co se má při startu JavaFX aplikace stát:
package cz.itnetwork.hellofx; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; import java.io.IOException; public class App extends Application { private static Scene scene; @Override public void start(Stage stage) throws IOException { scene = new Scene(loadFXML("primary"), 640, 480); stage.setScene(scene); stage.show(); } static void setRoot(String fxml) throws IOException { scene.setRoot(loadFXML(fxml)); } private static Parent loadFXML(String fxml) throws IOException { FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml")); return fxmlLoader.load(); } public static void main(String[] args) { launch(); } }
V metodě start() dostáváme pomocí parametru proměnnou typu
Stage. Této Stage potřebujeme nastavit nějakou
Scene, jinými slovy náš formulář. Máme zde pomocnou metodu
loadFXML(), která jako parametr bere název scény, již chceme
načíst. V našem případě načte scénu primary. Tuto pak
nastavíme ve stage pomocí setScene() a na závěr
celou stage zobrazíme pomocí show().
Další pomocná metoda, setRoot() nám umožňuje snadno za
běhu aplikace změnit zobrazovaný formulář za jiný, načtený z jiného
souboru.
Celý tento příklad nám ukazuje nejzákladnější vlastnosti typické JavaFX aplikace a sice, že GUI je odděleno od logiky a popsáno v FXML souborech, zatímco logika je v klasických Java souborech. Tento přístup umožňuje velice snadné a pohodlné úpravy vzhledu aplikace klidně i někým, kdo neovládá programování, ale má estetické cítění. V projektu tak mohou snadno spolupracovat grafik a programátor na opravdu pěkně vypadající aplikaci.
Tvorba Hello world
aplikace
Nyní, když už tušíme, jak v JavaFX spolupracují
.fxml a .java soubory, pojďme si upravit naší
aplikaci na klasické Hello world. Budeme v ní chtít zobrazit
tlačítko, které po kliknutí zobrazí hlášku Hello
world.
Nejprve odstraníme soubory, které nebudeme potřebovat. Necháme si pouze
soubor App.java. V jeho metodě start() změníme
načítání primary.fxml na hello.fxml:
... scene = new Scene(loadFXML("hello"), 640, 480); ...
Nyní si vytvoříme hello.fxml a příslušný kontroler
HelloController.java. Klikneme v okně Projects pravým
tlačítkem na náš balíček cz.itnetwork.hellofx a vybereme
New -> Empty FXML. Vyskočí na nás dialog, ve kterém nastavíme
název nového .fxml souboru na hello a
package změníme z defaultního fxml na
cz.itnetwork.hellofx, jako na následujícím obrázku:

Klikneme na Next a dostaneme se do formuláře vytvoření nového
kontroleru. Zaškrtneme Use Java Controller a pouze zkontrolujeme, že
se nám vytváří soubor s názvem HelloController.java v
balíčku cz.itnetwork.hellofx:

Opět klikneme na Next. Nastavením CSS se nebudeme zabývat, takže rovnou odklikneme Finish. Takto se nám vytvoří najednou oba soubory.
Nejprve si v NetBeans otevřeme kontroler
HelloController.java a doplníme do něj pár věcí. Předně
budeme potřebovat Label, který nám zobrazí hlášku
Hello world. Také budeme potřebovat metodu, která se spustí,
poté co klikneme na tlačítko. Už víme, že proměnné a metody, které
mají být použitelné ve FXML, je potřeba označit anotací
@FXML, takže kód kontroleru upravíme do následující
podoby:
public class HelloController implements Initializable { @FXML private Label helloLabel; @FXML public void buttonClicked() { helloLabel.setText("Hello world!!!"); } /** * Initializes the controller class. */ @Override public void initialize(URL url, ResourceBundle rb) { // TODO } }
Metodu initialize() nám v kontroleru vytvořilo NetBeans a
nyní si ji nebudeme všímat. Potřebné importy necháme automaticky doplnit
pomocí Ctrl+Shift+I.
Teď si otevřeme hello.fxml ve Scene Builderu
a z palety nalevo, ze sekce Controls přetáhneme na formulář
uprostřed Label a Button. Umístíme je někam
doprostřed (Scene Builder nám zobrazí pomocnou červenou čáru, když
komponentu budeme mít přesně uprostřed) jako na obrázku:

Nyní vybereme Label a napravo v sekci Properties
vymažeme Text. Label tak nebude zobrazovat při
spuštění aplikace nic, text se v zde objeví až po kliknutí na tlačítko.
Přesuneme se do sekce Code a nastavíme fx:id na
helloLabel.
Pak vybereme Button a v sekci Properties nastavíme
Text na Click me!, v sekci Code
nastavíme On Action na buttonClicked:

Stiskem CTRL+S formulář uložíme a přepneme se do NetBeans.
Ve skutečnosti nezáleží na tom, zda si nejprve vytvoříme
FXML v Scene Builderu nebo Java kontroler, ale když si nejprve
vytvoříme kontroler, můžeme pak ve Scene Builderu vyžívat
toho, že nám bude nabízet prvky z kontroleru označené anotací
@FXML.
Provedeme pro jistotu Clean and build projektu a po spuštění se
nám objeví okno s tlačítkem Click me. Po kliknutí na toto
tlačítko se nad ním objeví nápis Hello world:

Svůj projekt můžete porovnat s ukázkovou aplikací, která je ke stažení pod článkem v přiloženém zip souboru.
V příští lekci, Jednoduchá kalkulačka v JavaFX, si vytvoříme svou první jednoduchou aplikaci v JavaFX. Bude se jednat o kalkulačku.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 892x (5.77 kB)
Aplikace je včetně zdrojových kódů v jazyce Java


David se informační technologie naučil na