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 6 - Upomínač narozenin v Java Swing - Propojení vrstev

V minulém dílu seriálu, Upomínač narozenin v Java Swing - Logická vrstva, jsme dokončili základ logické vrstvy aplikace.

Dnes ji 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áře) 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 kódu formuláře! Vždy si vytvoříme třídu, která poskytuje příslušné metody a tuto třídu z formuláře 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 zdrojového kódu formuláře PrehledJFrame 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 konstruktoru formuláře nastavíme dnesJLabel na aktuální datum a JListu nastavíme vlastnost model na model ze správce osob. Tím napojíme JList na DefaultListModel, odteď bude zobrazovat jeho obsah a pokud se do modelu něco přidá, projeví se to i v JListu. Pokud jsou v modelu nějaké osoby, nastavíme vybranou položku JListu na první index.

public PrehledJFrame() {
    initComponents();
    dnesJLabel.setText(Datum.zformatuj(LocalDate.now()));
    osobyJList.setModel(spravceOsob.getModel());
    if (!spravceOsob.getOsoby().isEmpty()) {
        osobyJList.setSelectedIndex(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. Nejprve přejdeme do kódu dialogu OsobaJDialog, kde si přidáme privátní atribut typu osoba, ke kterému vygenerujeme getter. Až budeme dialog později zobrazovat, právě odtud si načteme osobu, jejíž údaje uživatel zadal.

private Osoba osoba = null;

 public Osoba getOsoba() {
    return osoba;
}

Nyní naklikneme tlačítko OK, kde se pokusíme vytvořit osobu na základě údajů, které uživatel zadal. Osobu uložíme do privátního atributu.

Pokud se něco nepovede, zobrazíme MessageDialog s chybou. 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.

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ávě řádek:

osoba = new Osoba(jmenoJTextField.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, i když k ní prakticky nedojde z důvodu použití JFormattedTex­tField. 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ě. Pomocí dispose() zavíráme aktuální formulář.

V tomto formuláři jsme skončili. Přesuneme se zpět do PrehledJFrame, tentokrát do grafické části a naklikneme tlačítka 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é metodě tlačítka pridejJButton vytvoříme novou instanci dialogu OsobaJDialog, které v konstruktoru nastavíme rodičovský formulář na aktuální instanci PrehledJFrame (this) a v druhém parametru nastavíme dialog jako modální. Jakmile se dialog dále zobrazí pomocí setVisible(true), zablokuje zbytek aplikace, který se zaktivní až v případě, kdy se dialog zavře. Výsledkem je, že se s hlavním formulářem nedá pracovat dokud dialog nepotvrdíme či neukončíme. U dialogu se toto většinou dělá, již jen proto, aby si uživatel nemohl ten samý dialog vyvolat vícekrát. I když nám by v podstatě nevadilo, kdyby uživatel během zadávání nové osoby aplikaci používal a otevřel třeba další dialog k zadávání. Osobu z dialogu si 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 ListModel, zobrazí se osoba ihned i v JListu na formuláři.

Obslužná metoda tlačítka odebratJButton bude vypadat takto:

private void odebratJButtonActionPerformed(java.awt.event.ActionEvent evt) {
    Osoba vybrana = (Osoba)osobyJList.getSelectedValue();
    if (vybrana != null) {
        spravceOsob.odeber(vybrana);
    }
}

JList může být inicializován 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, klikněte na JList a vyhledejte kartu Code umístěnou na stejném postranním panelu, kde jsou karty Properties a Events. Tam najdete možnost Type Parameters s hodnotou <String>. Jednoduše ji odeberte a vše bude fungovat.

Důležitá je podmínka, která zjišťuje, zda je v JListu vybraná nějaká položka. Jak vidíte, k vybrané položce se dostaneme přes vlastnost getSelectedValue. Položku následně přetypujeme na Osobu, jelikož je typu object (to aby byl JList univerzální). Tuto osobu předáme metodě odeber na správci, která dále vykoná fyzické odebrání z ListModelu.

Druhá možnost, jak zjistit, zda je v JListu vybrána nějaká položka, je použít na něm metodu isSelectionEmpty(). Ta vrací true, pokud není vybrána žádná položka. Naše metoda odebratJButtonActionPerformed() by pak vypadala takto:

private void odebratJButtonActionPerformed(java.awt.event.ActionEvent evt) {
        if (!osobyJList.isSelectionEmpty()) {
            spravceOsob.odeber((Osoba)osobyJList.getSelectedValue());
        }
}

Aplikaci si nyní můžete vyzkoušet, již půjde přidávat a odebírat osoby. Přidané osoby se ihned objeví v JListu díky bindingům. JList vždy zobrazuje to, co vrací metoda toString() objektu. U osob tedy zobrazuje jejich jméno.

Přidávání a odebírání položek v JListu v Java Swing - Základy Java Swing

Příště, Upomínač narozenin v Java Swing - 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 534x (19.47 kB)
Aplikace je včetně zdrojových kódů v jazyce Java

 

Předchozí článek
Upomínač narozenin v Java Swing - Logická vrstva
Všechny články v sekci
Základy Java Swing
Přeskočit článek
(nedoporučujeme)
Upomínač narozenin v Java Swing - Dokončení logiky
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
16 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