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 ji v Java tutoriálu propojíme s formulářem a 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 2 vrstvy se v aplikaci striktně oddělují, jelikož jinak je kód velmi nepřehledný. Nikdy byste neměli provádět výpočty, zápisy do souborů, databáze a podobné věci přímo v kontroleru formuláře! 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ě. 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á 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ě.
Propojení prezentace a logiky
Přejdeme do kontroleru formuláře a třídě přidáme privátní atribut typu SpravceOsob, ve kterém rovnou vytvoříme instanci správce:
private 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 ListView nastavíme položky na ObservableList ze správce osob. Odteď bude ListView zobrazovat obsah ObservableListu a pokud se do listu něco přidá, projeví se to i v ListView. Pokud jsou v listu nějaké osoby, nastavíme vybranou položku ListView na první index.
@Override public void initialize(URL url, ResourceBundle rb) { dnesLabel.setText(Datum.zformatuj(Calendar.getInstance())); 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.
Přejdeme do připravené obslužné metody dialogu, ta se nachází v metodě
vytvorObsahDialogu()
. 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. 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 spadnout.
dialog.setResultConverter(new Callback<ButtonType, Osoba>() { @Override public Osoba call(ButtonType param) { try { Calendar narozeniny = Datum.naparsuj(datumTextField.getText()); return new Osoba(jmenoTextField.getText(), narozeniny); } catch (ParseException | IllegalArgumentException ex) { System.out.println("Chyba: " + ex.getMessage()); Alert alert = new Alert(AlertType.ERROR, "Osobu se nepodařilo naparsovat!"); alert.showAndWait(); return null; } } });
Právě řádek:
return new Osoba(jmenoTextField.getText(), narozeniny);
Může vyvolat výjimku, jelikož výjimku přímo vyhazujeme v konstruktoru osoby v případě špatných údajů, můžete se tam podívat. Další výjimku může vyvolat i parsování datumu, 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 bloku try. V bloku 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.
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); final 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í i načteme a pokud tam nějaká je (uživatel dialog potvrdil tlačítkem OK a neodkřížkoval ho), přidáme osobu do správce. 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. Jak vidíte, k vybrané položce se dostaneme přes vlastnost getSelectedItem na SelectionModelu. Tuto osobu předáme metodě odeber na správci, která dále vykoná fyzické odebrání z ObservableListu.
Aplikaci si nyní můžete vyzkoušet, 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 tedy 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.
Stáhnout
Staženo 653x (182.07 kB)
Aplikace je včetně zdrojových kódů v jazyce java
Komentáře


Zobrazeno 10 zpráv z 13. Zobrazit vše