16. diel - Diár s databázou v Jave - Metódy diára, výnimky a final
V minulej lekcii, Diár s databázou v Jave - Záznam, databáza a diár, sme rozpracovali jednoduchý diár s databázou
pomocou kolekcie ArrayList
.
V dnešnom tutoriále aplikáciu dokončíme.
Trieda Diary
Do triedy Diary
pridajme dve pomocné metódy
readDateTime()
a readDate()
, ktoré vyzvú
používateľa na zadanie dátumu (a prípadne času) a vrátia inštanciu
LocalDateTime
nastavenú na túto hodnotu. Najprv si metódy
ukážme, čoskoro si ich popíšeme:
private LocalDateTime readDateTime() { System.out.println("Enter date and time as [" + LocalDateTime.now().format(DATE_FORMAT) + "]:"); while (true) { try { return LocalDateTime.parse(scanner.nextLine(), DATE_FORMAT); } catch (Exception ex) { System.out.println("Error. Please try again."); } } } private LocalDateTime readDate() { System.out.println("Enter date as [" + LocalDate.now().format(DATE_FORMAT_WITHOUT_TIME) + "]:"); while (true) { try { return LocalDate.parse(scanner.nextLine(), DATE_FORMAT_WITHOUT_TIME).atStartOfDay(); } catch (Exception ex) { System.out.println("Error. Please try again."); } } }
Pridáme ešte potrebné importy:
import java.time.LocalDateTime; import java.time.LocalDate;
Ako prvé vás zrejme upútajú neznáme bloky try
a
catch
. Názov pre tieto bloky sú výnimky, v
tejto lekcii ich rozoberať nebudeme, preberajú sa kompletne až v kurze o súboroch. Pre nás je momentálne iba
dôležité vedieť, že zachytia kritickú chybu a celá aplikácia vďaka tomu
nespadne. Ak teda triedy LocalDateTime
alebo
LocalDate
nedokážu naparsovať vstup od používateľa (tzn.
zadal chybný formát dátumu a času), vypíšeme hlášku, že nebol dátum
správne zadaný. Keďže máme tieto bloky v nekonečnom cykle
while
, bude sa to opakovať do doby, kým používateľ nezadá
správny formát dátumu.
Obe metódy formátujú dátum známou metódou format()
,
konštanty DATE_FORMAT
a DATE_FORMAT_WITHOUT_TIME
si o
chvíľu deklarujeme. Metóda readDate()
by bez času vracala
nechcený typ LocalDate
, vďaka tomu zavoláme v
return
metódu atStartOfDay()
aby sme vrátili
inštanciu triedy LocalDateTime
.
Pomocou metódy readDateTime()
budeme teda zadávať dátum a
čas, pomocou metódy readDate()
budeme zadávať iba dátum.
Druhá metóda bude slúžiť na vyhľadávanie záznamov v určitý deň,
pretože určite nebudeme chcieť odstrániť záznamy v danú hodinu a minútu,
ale záznamy v daný deň bez určenia času.
Konštanty
Do triedy si pridáme už spomínané verejné,
statické a finálne konštanty. Budú to
formattery dátumu a času. Kľúčové slovo final
si vysvetlíme
za chvíľu, statické a verejné atribúty to sú preto, aby boli použiteľné
aj pre ďalšie triedy v našej aplikácii bez vytvorenia inštancie. Každá
trieda môže používať tieto formattery, ktoré máme definované na jednom
mieste:
public static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("d.M.y H:mm"); public static final DateTimeFormatter DATE_FORMAT_WITHOUT_TIME = DateTimeFormatter.ofPattern("d.M.y");
Pridáme si ďalší potrebný import:
import java.time.format.DateTimeFormatter;
Kľúčové slovo final
Toto kľúčové slovo sa môže deklarovať na premennej, atribúte, metóde alebo aj na triede.
Na premennej alebo atribúte
Kľúčové slovo final
na atribúte/premennej zamedzí
tomu, aby sa daný atribút/premenná mohla naďalej meniť, bude teda
konštantná (vždy rovnaká). Hodnota do premennej/atribútu
sa nemusí priradiť ihneď po deklarácii, ale pokojne až v priebehu. Má to
však aj malý háčik, ak deklarujeme napríklad:
public final Human human;
Do atribútu human
už nebudeme môcť priradiť nového
človeka, budeme však môcť stále meniť jeho atribúty, napríklad
human.age = 18
. Atribút teda nie je v tomto prípade kompletne
nemenný. Aby nebolo možné zmeniť aj vek inštancie human
,
museli by sme pridať kľúčové slovo final
aj atribútu
age
v triede Human
.
Na triede
Finálna trieda sa už nemôže zmeniť a nemôže sa z nej ani dediť.
Na metódach
Finálne metódy nemôžu byť prepísané (@Override
) alebo
skryté potomkom.
Súbor Entry.java
Jeden formatter obsahuje dátum aj čas, jeden iba dátum bez času. Prejdime
do triedy Entry.java
a metódu toString()
pozmeňme
takto:
@Override public String toString() { return Diary.DATE_FORMAT.format(dateTime) + " " + text; }
Keby sme si robili inštanciu formatteru znova v každom zázname, bolo by to
nepraktické. Takto máme formattery na jednom mieste a keď sa rozhodneme
formát zmeniť, zmeníme ho len v triede Diary
. So statikou ale
opatrne, nie vždy je vhodné ju použiť.
Súbor Diary.java
Presunieme sa späť do súboru Diary.java
, kde si pridáme
ďalšie metódy.
Metóda printEntries()
Pridajme metódu printEntries()
, ktorá nájde záznamy v daný
deň a vypíše ich:
public void printEntries(LocalDateTime day) { ArrayList<Entry> entries = database.findEntries(day, false); for (Entry entry : entries) { System.out.println(entry); } }
Pridáme ďalší import:
import java.util.ArrayList;
Metóda addEntry()
Metóda pre vyzvanie používateľa na vloženie parametrov nového záznamu a jeho pridanie do databázy bude nasledujúca:
public void addEntry() { LocalDateTime dateTime = readDateTime(); System.out.println("Enter the entry text:"); String text = scanner.nextLine(); database.addEntry(dateTime, text); }
Metóda searchEntries()
Zostáva záznamy vyhľadávať a mazať. Metóda na vyhľadanie vráti
kolekciu ArrayList
s nájdenými záznamami (len podľa dátumu,
presný čas nebude hrať rolu). Vyzveme používateľa na zadanie dátumu a to
odovzdáme databáze. Výsledok zobrazíme:
public void searchEntries() { // Entering the date LocalDateTime dateTime = readDate(); // Searching for entries ArrayList<Entry> entries = database.findEntries(dateTime, false); // Printing entries if (entries.size() > 0) { System.out.println("Entries found: "); for (Entry entry : entries) { System.out.println(entry); } } else { System.out.println("No entries were found."); } }
Metóda deleteEntries()
Mazanie záznamov je triviálne:
public void deleteEntries() { System.out.println("Entries with the same exact date and time will be deleted"); LocalDateTime dateTime = readDateTime(); database.deleteEntries(dateTime); }
Metóda printHomeScreen()
Ako poslednú pridajme metódu na vypísanie úvodnej obrazovky programu s aktuálnym dátumom a časom a udalosťami na dnešok a zajtrajšok.
public void printHomeScreen() { System.out.println(); System.out.println(); System.out.println("Welcome to diary!"); LocalDateTime today = LocalDateTime.now(); System.out.printf("Today is: %s%n", DATE_FORMAT.format(today)); System.out.println(); // printing the home screen System.out.println("Today:\n-----"); printEntries(today); System.out.println(); System.out.println("Tomorrow:\n------"); LocalDateTime tomorrow = LocalDateTime.now().plusDays(1); printEntries(tomorrow); System.out.println(); }
Súbor Journal.java
Môžeme víťazoslávne prejsť do hlavného súboru
Journal.java
a vytvoriť inštanciu diára. Tu umiestnime aj
hlavný cyklus programu s menu programu a reakciou na voľbu používateľa. Je
to tá najvyššia vrstva programu:
Scanner scanner = new Scanner(System.in); Diary diary = new Diary(); String choice = ""; // main loop while (!choice.equals("4")) { diary.printHomeScreen(); System.out.println(); System.out.println("Choose an action:"); System.out.println("1 - Add an entry"); System.out.println("2 - Search for entries"); System.out.println("3 - Delete entries"); System.out.println("4 - End"); choice = scanner.nextLine(); System.out.println(); // reaction to the choice switch (choice) { case "1": diary.addEntry(); break; case "2": diary.searchEntries(); break; case "3": diary.deleteEntries(); break; case "4": // quits the loop, which terminates the program break; default: System.out.println("Error. Try again."); break; } }
Kód vyššie nie je zložitý a podobný sme tu už mali veľakrát.
Nezabudneme pridať ešte import pre Scanner
:
import java.util.Scanner;
Výslednú aplikáciu som na vyskúšanie požičal priateľke, nižšie vidíme výsledok 🙂:
Konzolová aplikácia
Welcome to diary!
Today is: 13.4.2023 20:22
Today
-----
13.4.2023 10:00 Shopping - Pankrac Arcade
13.4.2023 19:30 Walk my Yorkshire Terrier Fred
Tomorrow:
------
14.4.2023 14:00 Power plate
Choose an action:
1 - Add an entry
2 - Search for entries
3 - Delete entries
4 - End
2
Enter date as [13.4.2023]:
15.4.2023
Found entries:
15.4.2023 9:30 Economy exam
Týmto sme si kolekciu ArrayList
osvojili a bude nám pomerne
dlho stačiť. Na záver by som dodal, že takto si môžete urobiť databázu
čohokoľvek. Môžete použiť napr. triedu Student
z lekcie Gettery a settery v
Jave alebo ktorúkoľvek inú triedu. Môžete ukladať články, úlohy,
slony, čokoľvek, čo chcete v databáze spravovať. A čo ďalej?
V nasledujúcej lekcii, Rozhranie (interface) v Jave, si vysvetlíme, čo je to rozhranie.
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é 12x (5.38 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java