Lekce 17 - Diář s databází v Javě - Metody diáře, výjimky a final
V minulé lekci, Diář s databází v Javě - Záznam, databáze a diář, jsme rozpracovali jednoduchý diář s
databází pomocí kolekce ArrayList
.
V dnešním tutoriálu aplikaci dokončíme.
Třída Diar
Do třídy Diar
přidejme dvě pomocné metody
naparsujDatumCas()
a naparsujDatum()
, které vyzvou
uživatele k zadání data (a případně času) a vrátí instanci
LocalDateTime
nastavenou na tuto hodnotu. Nejprve si metody
ukažme, záhy si je popíšeme:
private LocalDateTime naparsujDatumCas() { System.out.println("Zadejte datum a čas ve tvaru [" + LocalDateTime.now().format(FORMAT_DATA) + "]:"); while (true) { try { return LocalDateTime.parse(scanner.nextLine(), FORMAT_DATA); } catch (Exception ex) { System.out.println("Nesprávně zadáno, zadejte prosím znovu."); } } } private LocalDateTime naparsujDatum() { System.out.println("Zadejte datum ve tvaru [" + LocalDate.now().format(FORMAT_DATA_BEZ_CASU) + "]:"); while (true) { try { return LocalDate.parse(scanner.nextLine(), FORMAT_DATA_BEZ_CASU).atStartOfDay(); } catch (Exception ex) { System.out.println("Nesprávně zadáno, zadejte prosím znovu."); } } }
Přidáme ještě potřebné importy:
import java.time.LocalDateTime; import java.time.LocalDate;
Jako první vás bodne do oka nejspíš neznámé bloky try
a
catch
. Název pro tyto bloky jsou výjimky, v
této lekci je rozebírat nebudeme, probírají se kompletně až v kurzu o souborech. Pro nás je momentálně pouze
důležité vědět, že zachytí kritickou chybu a celá aplikace díky tomu
nespadne. Pokud tedy třídy LocalDateTime
nebo
LocalDate
nedokážou naparsovat vstup od uživatele (tzn. že
zadal chybný formát data a času), vypíšeme hlášku, že nebylo datum
správně zadáno. Jelikož máme tyto bloky v nekonečném cyklu
while
, bude se to opakovat do doby, dokud uživatel nezadá
správný formát datumu.
Obě metody formátují datum známou metodou format()
,
konstanty FORMAT_DATA
a FORMAT_DATA_BEZ_CASU
si za
chvíli deklarujeme. Metoda naparsujDatum()
by bez času vracelo
nechtěný typ LocalDate
, díky tomu zavoláme v
return
metodu atStartOfDay()
abychom vrátili instanci
třídy LocalDateTime
.
Pomocí metody naparsujDatumCas()
budeme tedy zadávat datum a
čas, pomocí metody naparsujDatum()
budeme zadávat pouze datum.
Druhá metoda bude sloužit k vyhledávání záznamů v určitý den, jelikož
určitě nebudeme chtít odstranit záznamy v danou hodinu a minutu, ale
záznamy v daný den bez určení času.
Konstanty
Do třídy si přidáme již zmíněné veřejné,
statické a finální konstanty. Budou to
formattery data a času. Klíčové slovo final
si vysvětlíme za
chvíli, statické a veřejné atributy to jsou proto, aby byly použitelné i
pro další třídy v naší aplikaci bez vytvoření instance. Každá třída
může používat tyto formattery, které máme definované na jednom
místě:
public static final DateTimeFormatter FORMAT_DATA = DateTimeFormatter.ofPattern("d.M.y H:mm"); public static final DateTimeFormatter FORMAT_DATA_BEZ_CASU = DateTimeFormatter.ofPattern("d.M.y");
Přidáme si další potřebný import:
import java.time.format.DateTimeFormatter;
Klíčové slovo final
Toto klíčové slovo se může deklarovat na proměnné, atributu, metody nebo i třídy.
Na proměnné nebo atributu
Klíčové slovo final
na atributu/proměnné zamezí
tomu, aby se daný atribut/proměnná mohla nadále měnit, bude tedy
konstantní (vždy stejná). Hodnota do proměnné/atributu se
nemusí ihned po deklaraci přiřadit, ale klidně až v průběhu. Má to však
i malý háček, pokud deklarujeme například:
public final Clovek clovek;
Do atributu clovek
už nebudeme moct přiřadit nového
člověka, budeme moct však stále měnit jeho atributy, například
clovek.vek = 18
. Atribut tedy není v tomto případě kompletně
neměnný. Aby nebylo možné změnit i věk instance clovek
,
museli bychom přidat klíčové slovo final
i atributu
vek
ve třídě Clovek
.
Na třídě
Finální třída se už nemůže změnit a nemůže se z ní ani dědit.
Na metodách
Finální metody nemohou být přepsány (@Override
) nebo skryty
potomkem.
Soubor Zaznam.java
Jeden formatter obsahuje datum i čas, jeden pouze datum bez času.
Přejděme do třídy Zaznam.java
a metodu toString()
pozměňme takto:
@Override public String toString() { return Diar.FORMAT_DATA.format(datumCas) + " " + text; }
Kdybychom si dělali instanci formatteru znovu v každém záznamu, bylo by
to nepraktické. Takto máme formattery na jednom místě a když se rozhodneme
formát změnit, změníme ho jen ve třídě Diar
. Se statikou ale
opatrně, ne vždy ji je vhodné použít.
Soubor Diar.java
Přesuneme se zpět do souboru Diar.java
, kde si přidáme
další metody.
Metoda vypisZaznamy()
Přidejme metodu vypisZaznamy()
, která najde záznamy v daný
den a vypíše je:
public void vypisZaznamy(LocalDateTime den) { ArrayList<Zaznam> zaznamy = databaze.najdiZaznamy(den, false); for (Zaznam zaznam : zaznamy) { System.out.println(zaznam); } }
Přidáme další import:
import java.util.ArrayList;
Metoda pridejZaznam()
Metoda pro vyzvání uživatele k vložení parametrů nového záznamu a jeho přidání do databáze bude následující:
public void pridejZaznam() { LocalDateTime datumCas = naparsujDatumCas(); System.out.println("Zadejte text záznamu:"); String text = scanner.nextLine(); databaze.pridejZaznam(datumCas, text); }
Metoda vyhledejZaznamy()
Zbývá záznamy vyhledávat a mazat. Metoda k vyhledání vrátí kolekci
ArrayList
s nalezenými záznamy (jen podle data, přesný čas
nebude hrát roli). Vyzveme uživatele k zadání data a to předáme databázi.
Výsledek zobrazíme:
public void vyhledejZaznamy() { // Zadání data uživatelem LocalDateTime datumCas = naparsujDatum(); // Vyhledání záznamů ArrayList<Zaznam> zaznamy = databaze.najdiZaznamy(datumCas, false); // Výpis záznamů if (zaznamy.size() > 0) { System.out.println("Nalezeny tyto záznamy: "); for (Zaznam zaznam : zaznamy) { System.out.println(zaznam); } } else { System.out.println("Nebyly nalezeny žádné záznamy."); } }
Metoda vymazZaznamy()
Mazání záznamů je triviální:
public void vymazZaznamy() { System.out.println("Budou vymazány záznamy v daný den a hodinu"); LocalDateTime datumCas = naparsujDatumCas(); databaze.vymazZaznamy(datumCas); }
Metoda
vypisUvodniObrazovku()
Jako poslední přidejme metodu pro vypsání úvodní obrazovky programu s aktuálním datem a časem a událostmi na dnešek a zítřek.
public void vypisUvodniObrazovku() { System.out.println(); System.out.println(); System.out.println("Vítejte v diáři!"); LocalDateTime dnes = LocalDateTime.now(); System.out.printf("Dnes je: %s%n", FORMAT_DATA.format(dnes)); System.out.println(); // výpis hlavní obrazovky System.out.println("Dnes:\n-----"); vypisZaznamy(dnes); System.out.println(); System.out.println("Zítra:\n------"); LocalDateTime zitra = LocalDateTime.now().plusDays(1); vypisZaznamy(zitra); System.out.println(); }
Soubor Poznamkovac.java
Můžeme vítězoslavně přejít do hlavního souboru
Poznamkovac.java
a vytvořit instanci diáře. Zde umístíme také
hlavní cyklus programu s menu programu a reakcí na volbu uživatele. Je to ta
nejvyšší vrstva programu:
Scanner scanner = new Scanner(System.in); Diar diar = new Diar(); String volba = ""; // hlavní cyklus while (!volba.equals("4")) { diar.vypisUvodniObrazovku(); System.out.println(); System.out.println("Vyberte si akci:"); System.out.println("1 - Přidat záznam"); System.out.println("2 - Vyhledat záznamy"); System.out.println("3 - Vymazat záznam"); System.out.println("4 - Konec"); volba = scanner.nextLine(); System.out.println(); // reakce na volbu switch (volba) { case "1": diar.pridejZaznam(); break; case "2": diar.vyhledejZaznamy(); break; case "3": diar.vymazZaznamy(); break; case "4": // vyskočí z cyklu while a tím ukončí program break; default: System.out.println("Neplatná volba, stiskněte libovolnou klávesu a opakujte volbu."); break; } }
Kód výše není složitý a již jsme tu podobný měli mockrát.
Nezapomeneme přidat ještě import pro Scanner
:
import java.util.Scanner;
Výslednou aplikaci jsem na vyzkoušení půjčil přítelkyni, níže vidíme výsledek 🙂:
Konzolová aplikace
Vítejte v diáři!
Dnes je: 13.4.2023 20:22
Dnes:
-----
13.4.2023 10:00 Shopping - Arkády Pankrác
13.4.2023 19:30 Vyvenčit mého yorkšírka Dennyho
Zítra:
------
14.4.2023 14:00 Power plate
Vyberte si akci:
1 - Přidat záznam
2 - Vyhledat záznamy
3 - Vymazat záznam
4 - Konec
2
Zadejte datum ve tvaru [13.4.2023]:
15.4.2023
Nalezeny tyto záznamy:
15.4.2023 9:30 Zkouška - Ekonomika cestovního ruchu
Tímto jsme si kolekci ArrayList
osvojili a bude nám poměrně
dlouho stačit. Na závěr bych dodal, že takto si můžete udělat databázi
čehokoli. Můžete použít např. třídu Student
z lekce Gettery a settery v
Javě nebo kteroukoli jinou třídu. Můžete ukládat články, úlohy,
slony, cokoli, co chcete v databázi spravovat. A co dál?
V příští lekci, Rozhraní (interface) v Javě, si vysvětlíme, co je to rozhraní.
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 1590x (25.87 kB)
Aplikace je včetně zdrojových kódů v jazyce Java