Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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:

Scene Builder s otevřeným primary.fxml - Java FX - Okenní aplikace

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:

Vlastnosti v Scene Builder - Java FX - Okenní aplikace

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():

fxid v Scene Builder - Java FX - Okenní aplikace

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:

Tvorba nového FXML souboru - Java FX - Okenní aplikace

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:

Vytvoření nového kontroleru - Java FX - Okenní aplikace

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:

Základní layout Hello world aplikace - Java FX - Okenní aplikace

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:

Nastavení On Action - Java FX - Okenní aplikace

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:

výsledné Hello world - Java FX - Okenní aplikace

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

 

Předchozí článek
Úvod do JavaFX
Všechny články v sekci
Java FX - Okenní aplikace
Přeskočit článek
(nedoporučujeme)
Jednoduchá kalkulačka v JavaFX
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
45 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity