6. diel - PRIPOMIENKOVÉ narodenín v Java Swing - Prepojenie vrstiev
V minulom dieli seriálu tutoriálov o tvorbe formulárových aplikácií v Java Swing sme dokončili základ logické vrstvy aplikácie. Dnes ju prepojíme s formulárom a aplikáciu tak sprevádzkujeme.
Prepojenie prezentačné a logické vrstvy
Teraz máme dokončenú tzv. Prezentačné časť aplikácie (formulára) a logickú časť (triedy). Tieto 2 vrstvy sa v aplikácii striktne oddeľujú, pretože inak je kód veľmi neprehľadný. Nikdy by ste nemali vykonávať výpočty, zápisy do súborov, databázy a podobné veci priamo v kóde formulára! Vždy si vytvoríme triedu, ktorá poskytuje príslušné metódy a túto triedu z formulára iba používame. Logika zostane v triede. Trieda by naopak vôbec nemala vedieť o formulári. Nemala by teda napr. Zobrazovať chybové hlášky, ale iba vyhadzovať v prípade chyby výnimky. Je potom na formulári, aby užívateľovi chybu zobrazil. Práve formulár je tá časť aplikácie, ktorá s užívateľom komunikuje. Žiadna iná to nerobí.
Ak vás napadlo, že naše jednoduchá kalkulačka, ktorú sme vytvorili v prvých dieloch seriálu, bola návrhové zle, máte pravdu. Z dôvodu jednoduchosti sme napísali výpočty rovno do obslužnej metódy tlačidla. Správne by sme mali mať nejakú triedu, ktorá by výsledky počítala a tú by sme z formulára iba volali.
Ukážeme si teda, ako sa to robí správne.
Prepojenie prezentácie a logiky
Prejdeme do zdrojového kódu formulára PrehledJFrame a triede pridáme privátne atribút typu SpravceOsob, v ktorom rovno vytvoríme inštanciu správcu:
private SpravceOsob spravceOsob = new SpravceOsob();
Inštancie správcu sa vytvorí pri vytvorení formulára a formulár s ňou ďalej bude komunikovať a tak vykonávať úkony, ktoré si želá užívateľ.
V konstruktoru formuláre nastavíme dnesJLabel na aktuálny dátum a JListu nastavíme vlastnosť model na model zo správcu osôb. Tým napojíme JList na DefaultListModel, odteraz bude zobrazovať jeho obsah a ak sa do modelu niečo pridá, prejaví sa to aj v JListu. Pokiaľ sú v modeli nejakej osoby, nastavíme vybranú položku JListu na prvý index.
public PrehledJFrame() { initComponents(); dnesJLabel.setText(Datum.zformatuj(LocalDate.now())); osobyJList.setModel(spravceOsob.getModel()); if (!spravceOsob.getOsoby().isEmpty()) { osobyJList.setSelectedIndex(0); } }
Pridávanie a mazanie osôb
Aby sme niečo konečne tiež videli, prejdeme k pridávanie osôb. Najprv prejdeme do kódu dialógu OsobaJDialog, kde si pridáme privátne atribút typu osoba, ku ktorému vygenerujeme getter. Až budeme dialóg neskôr zobrazovať, práve odtiaľ si načítame osobu, ktorej údaje užívateľ zadal.
private Osoba osoba = null; public Osoba getOsoba() { return osoba; }
Teraz naklikne tlačidlo OK, kde sa pokúsime vytvoriť osobu na základe údajov, ktoré užívateľ zadal. Osobu uložíme do privátneho atribútu.
Ak sa niečo nepodarí, zobrazíme MessageDialog s chybou. Iste ste sa už stretli s konštrukciou try-catch, ktorá umožňuje odchytiť vyvolané výnimky a nejako na tieto chyby reagovať namiesto toho, aby sme nechali aplikáciu spadnúť.
private void okJButtonActionPerformed(java.awt.event.ActionEvent evt) { try { LocalDate narozeniny = Datum.naparsuj(narozeninyJFormattedTextField.getText()); osoba = new Osoba(jmenoJTextField.getText(), narozeniny); dispose(); } catch (ParseException | IllegalArgumentException ex) { JOptionPane.showMessageDialog(null, "Chyba: " + ex.getMessage()); } }
Práve riadok:
osoba = new Osoba(jmenoJTextField.getText(), narozeniny);
Môže vyvolať výnimku, pretože výnimku priamo vyhadzujeme v konstruktoru osoby v prípade zlých údajov, môžete sa tam pozrieť. Ďalšie výnimku môže vyvolať aj parsovanie datumu, aj keď k nej prakticky nedôjde z dôvodu použitia JFormattedTextField. Kód, ktorý výnimku vyvoláva, umiestnime do bloku try. V bloku catch potom výnimku odchytíme a zobrazíme jej správu užívateľovi. Ak všetko prebehne hladko, program sa do bloku catch ani nedostane. Výnimky väčšinou vyvolávame v logických triedach a potom ich chytáme vo formulároch. Výnimky sú podrobnejšie opísané v článku Výnimky v Jave. Pomocou dispose () zatvárame aktuálny formulár.
V tomto formulári sme skončili. Presunieme sa späť do PrehledJFrame, tentoraz do grafickej časti a naklikne tlačidlá pridatJButton a odebratJButton.
private void pridatJButtonActionPerformed(java.awt.event.ActionEvent evt) { OsobaJDialog osobaJDialog = new OsobaJDialog(this, true); osobaJDialog.setLocationRelativeTo(null); osobaJDialog.setVisible(true); Osoba nova = osobaJDialog.getOsoba(); if (nova != null) { spravceOsob.pridej(nova); } }
V obslužné metóde tlačidla pridejJButton vytvoríme novú inštanciu dialógu OsobaJDialog, ktoré v konstruktoru nastavíme rodičovský formulár na aktuálnu inštanciu PrehledJFrame (this) a v druhom parametri nastavíme dialóg ako modálne. Akonáhle sa dialóg ďalej zobrazí pomocou setVisible (true), zablokuje zvyšok aplikácie, ktorý sa zaktivní až v prípade, keď sa dialóg zatvorí. Výsledkom je, že sa s hlavným formulárom nedá pracovať kým dialóg nepotvrdíme či neukončíme. U dialógu sa toto väčšinou robí, už len preto, aby si užívateľ nemohol ten istý dialóg vyvolať viackrát. Aj keď nám by v podstate nevadilo, keby užívateľ počas zadávania novej osoby aplikáciu používal a otvoril potrebné ďalšie dialóg na zadávanie. Osobu z dialógu si načítame a ak tam nejaká je (užívateľ dialóg potvrdil tlačidlom OK a neodkřížkoval ho), pridáme osobu do správcu. Pretože používame ListModel, zobrazí sa osoba ihneď aj v JListu na formulári.
Obslužná metóda tlačidla odebratJButton bude vyzerať takto:
private void odebratJButtonActionPerformed(java.awt.event.ActionEvent evt) { Osoba vybrana = (Osoba)osobyJList.getSelectedValue(); if (vybrana != null) { spravceOsob.odeber(vybrana); } }
JList
môže byť inicializovaný s Type Parameter nastaveným
jako` String
, který by pak vyvolal chybu. Pokud se jedná o váš případ, přejděte na kartu Design komponenty `OverviewJFrame
,
kliknite na JList
a vyhľadajte kartu Code umiestnenú na rovnakom
bočnom paneli, kde sú karty Properties a Events. Tam nájdete možnosť
Type Parameters
s hodnotou <String>
. Jednoducho
ju odoberte a všetko bude fungovať.
Dôležitá je podmienka, ktorá zisťuje, či je v JListu vybraná nejaká položka. Ako vidíte, k vybranej položke sa dostaneme cez vlastnosť getSelectedValue. Položku následne přetypujeme na Osobu, pretože je typu object (to aby bol JList univerzálne). Túto osobu odovzdáme metóde odober na správcovi, ktorá ďalej vykoná fyzické odobratie z ListModelu.
Aplikáciu si teraz môžete vyskúšať, už pôjde pridávať a odoberať osoby. Pridanej osoby sa ihneď objaví v JListu vďaka bindingům. JList vždy zobrazuje to, čo vracia metóda toString () objektu. U osôb teda zobrazuje ich meno.
Nabudúce doplníme logickú vrstvu aplikácie o ďalšie metódy a tým ju dokončíme.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 541x (19.47 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java