Lekce 7 - Upomínač narozenin v JavaFX - Propojení vrstev
V minulé lekci, Upomínač narozenin v JavaFX - Logická vrstva, jsme dokončili základ logické vrstvy aplikace.
Dnes si v JavaFX tutoriálu propojíme logickou vrstvu s formulářem a naši aplikaci tak zprovozníme.
Propojení prezentační a logické vrstvy
Nyní máme dokončenou tzv. prezentační část aplikace (formulář) a logickou část (třídy). Tyto dvě vrstvy se v aplikaci striktně oddělují, jelikož jinak je kód velmi nepřehledný. Vždy si vytvoříme třídu, která poskytuje příslušné metody a tuto třídu z kontroleru pouze používáme. Logika zůstane ve třídě.
Nikdy bychom neměli provádět výpočty, zápisy do souborů či databáze a podobné věci přímo v kontroleru formuláře!
Třída by naopak vůbec neměla vědět o formuláři. Neměla by tedy např. zobrazovat chybové hlášky, ale pouze vyhazovat v případě chyby výjimky. Je potom na formuláři, aby uživateli chybu zobrazil. Právě formulář je ta část aplikace, která s uživatelem komunikuje. Žádná jiná část to nedělá.
Pokud vás napadlo, že naše jednoduchá kalkulačka, kterou jsme vytvořili v prvních dílech seriálu, byla návrhově špatně, máte pravdu. Z důvodu jednoduchosti jsme napsali výpočty rovnou do obslužné metody tlačítka. Správně bychom měli mít nějakou třídu, která by výsledky počítala a tu bychom z formuláře pouze volali.
Ukážeme si tedy, jak se to dělá správně.
Úprava kontroleru
Přejdeme do kontroleru formuláře a přidáme do něj privátní atribut
typu SpravceOsob
, ve kterém rovnou vytvoříme instanci
správce:
private final SpravceOsob spravceOsob = new SpravceOsob();
Instance správce se vytvoří při vytvoření formuláře a formulář s ní dále bude komunikovat a tak provádět úkony, které si přeje uživatel.
V metodě initialize()
nastavíme dnesLabel
na
aktuální datum a do ListView
nastavíme položky, které obsahuje
ObservableList
ze správce osob. Odteď bude ListView
zobrazovat obsah naší kolekce ObservableList
. Pokud se do seznamu
něco přidá, projeví se to i v ListView
. Pokud jsou v kolekci
ObservableList
nějaké osoby, nastavíme vybranou položku
ListView
na první index:
@Override public void initialize(URL url, ResourceBundle rb) { dnesLabel.setText(Datum.zformatuj(LocalDate.now())); osobyListView.setItems(spravceOsob.getOsoby()); if (!spravceOsob.getOsoby().isEmpty()) { osobyListView.getSelectionModel().select(0); } }
Přidávání a mazání osob
Abychom něco konečně také viděli, přejdeme k přidávání osob a
upravíme připravenou obslužnou metodu dialogu. Najdeme si tedy metodu
call()
, která se nachází v metodě
vytvorObsahDialogu()
, a upravíme ji. Zde se pokusíme vytvořit a
vrátit osobu na základě údajů, které uživatel zadal. Pokud se něco
nepovede, vypíšeme chybu:
dialog.setResultConverter(new Callback<ButtonType, Osoba>() { @Override public Osoba call(ButtonType param) { try { LocalDate narozeniny = Datum.naparsuj(datumTextField.getText()); return new Osoba(jmenoTextField.getText(), narozeniny); } catch (DateTimeParseException | IllegalArgumentException ex) { System.out.println("Chyba: " + ex.getMessage()); Alert alert = new Alert(AlertType.ERROR, "Osobu se nepodařilo naparsovat!"); alert.showAndWait(); return null; } } });
Jistě jste se již setkali s konstrukcí
try-catch
, která umožňuje odchytit vyvolané výjimky a nějak
na tyto chyby reagovat. Místo toho, abychom nechali aplikaci v případě
špatného zadání spadnout, použijeme try-catch
blok, který
případnou výjimku odchytí.
V uvedeném kódu může vyvolat výjimku řádek:
return new Osoba(jmenoTextField.getText(), narozeniny);
Je to proto, že výjimku přímo vyhazujeme v konstruktoru třídy
Osoba
v případě špatných údajů, tedy pokud je jméno
kratší tří znaků nebo pokud uživatel zadá budoucí datum. Další
výjimku může vyvolat i parsování data, protože do TextFieldu
může uživatel napsat prakticky cokoli a komponentu pro datum jsme nepoužili.
Kód, který výjimku vyvolává, umístíme do části try
. V
části catch
poté výjimku odchytíme a zobrazíme její zprávu
uživateli. Pokud vše proběhne hladce, program se do bloku catch
ani nedostane.
Výjimky většinou vyvoláváme v logických třídách a potom je chytáme ve formulářích. Výjimky jsou podrobněji popsané v článku Výjimky v Javě.
Chybovou hlášku vypíšeme do konzole. Uživateli zobrazíme pěkný dialog s informací, že se osobu nepodařilo vytvořit.
Doplnění obslužných metod tlačítek
V této metodě jsme skončili. Přesuneme se zpět do obslužných metod tlačítek Přidat a Odebrat a doplníme jejich kód:
@FXML public void handlePridatButtonAction(ActionEvent event) { Dialog<Osoba> dialog = new Dialog<>(); dialog.setTitle("Nová osoba"); dialog.setWidth(350); dialog.setHeight(250); vytvorObsahDialogu(dialog); Optional<Osoba> vysledek = dialog.showAndWait(); if (vysledek.isPresent()) { Osoba osoba = vysledek.get(); spravceOsob.pridej(osoba); } }
V obslužné metodě tlačítka pridatButton
již vytváříme
novou instanci dialogu. Osobu z dialogu si nyní zkusíme načíst. Pokud tam
nějaká je, přidáme osobu do správce. Uživatel totiž může dialog jednak
odeslat, tedy potvrdit tlačítkem OK
, ale také ho může pouze
zavřít křížkem. Protože používáme ObservableList
, zobrazí
se osoba ihned i v ListView
na formuláři.
Obslužná metoda tlačítka odebratButton
bude vypadat
takto:
@FXML public void handleOdebratButtonAction(ActionEvent event) { Osoba vybrana = osobyListView.getSelectionModel().getSelectedItem(); if (vybrana != null) { spravceOsob.odeber(vybrana); } }
Důležitá je podmínka, která zjišťuje, zda je v ListView
vybraná nějaká položka. Vidíme, že se k vybrané položce dostaneme
pomocí metody getSelectedItem()
, kterou voláme na
SelectionModel
. Získanou osobu předáme metodě
odeber()
na správci, která dále vykoná fyzické odebrání z
kolekce ObservableList
.
Aplikaci si nyní vyzkoušejme, již půjde přidávat a odebírat osoby.
Přidané osoby se ihned objeví v ListView
díky tomu, že
používáme ObservableList
. ListView
vždy zobrazuje
to, co vrací metoda toString()
objektu. U osob se tedy nyní
zobrazuje jejich jméno:
V příští lekci, Upomínač narozenin v JavaFX - Dokončení logiky, doplníme logickou vrstvu aplikace o další metody a tím ji dokončíme.
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 679x (11.17 kB)
Aplikace je včetně zdrojových kódů v jazyce Java