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 888x (5.77 kB)
Aplikace je včetně zdrojových kódů v jazyce Java