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

David se informační technologie naučil na