Zarábaj až 6 000 € mesačne! Akreditované rekvalifikačné kurzy od 0 €. Viac informácií.

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

 

Predchádzajúci článok
Diár s databázou v Jave - Záznam, databáza a diár
Všetky články v sekcii
Objektovo orientované programovanie v Jave
Preskočiť článok
(neodporúčame)
Rozhranie (interface) v Jave
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
21 hlasov
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 sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity