6. díl - Upomínač narozenin v Java Swing - Propojení vrstev

Java Swing Upomínač narozenin v Java Swing - Propojení vrstev

V minulém dílu seriálu tutoriálů o tvorbě formulářových aplikací v Java Swing 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(Calendar.getInstance()));
        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
        {
                Calendar 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);
        }
}

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.

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

Příště doplníme logickou vrstvu aplikace o další metody a tím ji dokončíme.


 

Stáhnout

Staženo 312x (43.04 kB)
Aplikace je včetně zdrojových kódů v jazyce java

 

  Aktivity (1)

Článek pro vás napsal David Čápka
Avatar
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.

Jak se ti líbí článek?
Celkem (1 hlasů) :
55555


 



 

 

Komentáře

Avatar
Jan Otipka
Člen
Avatar
Jan Otipka:

@Deprecated public Object[] getSelectedValues()
Deprecated. As of JDK 1.7, replaced by JList.getSelec­tedValuesList()
jak upravit odebírání, když tahle metoda vrací string?

Editováno 23. května 11:55
 
Odpovědět 23. května 11:55
Avatar
Jan Otipka
Člen
Avatar
Odpovídá na Jan Otipka
Jan Otipka:

no tak upraveno takhle

int vybrana = osobyJList.get­SelectedIndex();
if (vybrana >= 0) {
spravceOsob.o­deber(vybrana);
}

SpravceOsob přidáno

public void odeber(int index) {
osoby.remove(in­dex);

}

 
Odpovědět 23. května 13:03
Avatar
Odpovídá na Jan Otipka
Roman Havelka:

V NetBeans se JList po nakliknuti aut. nastavi na String.
V zalozce CODE radek Type Parameter staci vymazat <String>
a ponechat policko prazdne
a vse jede jak ma.

 
Odpovědět 11. října 18:26
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 3 zpráv z 3.