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í.

5. diel - Práca s CSV súbormi v Kotlin - Načítanie objektov

V minulej lekcii, Práca s textovými súbormi v Kotlin , sme si ukázali zápis do textových súborov aj ich čítanie.

V dnešnom Kotline tutoriálu implementujeme do našej objektovej formulárovej aplikácie načítanie užívateľov z textového súboru vo formáte CSV.

Doplnenie triedy Databaze

Do triedy Databaze si najskôr pridáme metódu na načítanie užívateľov.

Metóda nacti()

Kód metódy je nasledujúci:

@Throws(IOException::class)
fun nacti() {
    // Nejprve vyprázdníme uzivatele.
    uzivatele.clear()
    // Pak projdeme všechny řádky v souboru, každý rozsekáme na části podle středníků,
    // rozdělené části pak použijeme pro přidání nového uživatele.
    for (radek in Files.readAllLines(soubor)) {
        val rozdeleno = radek.split(";".toRegex()).toTypedArray()
        pridejUzivatele(rozdeleno[0], rozdeleno[1].toInt(), LocalDate.parse(rozdeleno[2]))
    }
}

Na začiatku metódy kolekciu uzivatele vyprázdnime zavolaním metódy clear(). Súbor soubor budeme čítať riadok po riadku v cykle. Každý riadok rozdelíme metódou split(), ktoré odovzdáme oddeľovač ;. Následne do kolekcie uzivatele pomocou metódy pridejUzivatele() pridáme objekt s rozdelenými hodnotami.

Prezentačná vrstva aplikácie

Teraz sa pustíme do úpravy nášho formulára. Do neho si pripravíme nové formulárové prvky. Budeme chcieť docieliť nasledujúci vzhľad:

Ukážka konečnej podoby formulára - Súbory a práce s nimi v Kotlin

Otvoríme si formular.fxml v Scene Builderi a do nášho kontajnera VBox vložíme ďalšie dva kontajnery typu Pane. Prvá bude obsahovať dva popisky Label, ktorým vyplníme text podľa ukážky. Textu Databáze uživatelů zväčšíme písmo a nastavíme tučný font v záložke Properties.

Druhý Pane kontajner bude obsahovať tri vložené kontajnery. Ako prvé pridáme ScrollPane, v ktorom budeme zobrazovať zoznam užívateľov typu ListView. Potom doplníme ďalší Pane kontajner pre zobrazovanie detailu užívateľa. Ten bude obsahovať sedem Label popiskov - nadpis a popisok pre meno, vek a dátum registrácie, vždy so zodpovedajúcim prázdnym poľom na načítanie detailu. Pod kontajner vložíme naše tlačidlo Uložiť a doplníme tlačidlo na načítanie databázy.

Nakoniec pridáme posledný Pane, ktorý bude opäť obsahovať popisky pre nadpis a údaje o užívateľovi, ktorého chceme do databázy pridať. Pre zodpovedajúce prázdne polia ale tentoraz zvolíme TextField na zadanie mena, Spinner na výber veku a DatePicker, ktorý nám uľahčí zadanie dátumu registrácie. Pod kontajner nezabudneme doplniť ďalšie tlačidlo Pridať.

Doplnenie obsluhy formulára

Upravený formulár uložíme av IntelliJ si otvoríme náš kontrolér.

Deklarácia FXML premenných

V kontroléri najskôr deklarujeme nové premenné pre zoznam užívateľov a jednotlivé položky pre pridanie užívateľa a zobrazenie jeho detailu:

class DatabazeKontroler : Initializable {

    var databaze: Databaze? = null

    @FXML
    private lateinit var novyUzivatelVek: Spinner<Int>

    @FXML
    private lateinit var novyUzivatelJmeno: TextField

    @FXML
    private lateinit var novyUzivatelDatumRegistrace: DatePicker

    @FXML
    private lateinit var detailUzivatelJmenoLabel: Label

    @FXML
    private lateinit var detailUzivatelVekLabel: Label

    @FXML
    private lateinit var detailUzivatelDatumLabel: Label

    @FXML
    private var uzivateleList: ListView<Uzivatel> = ListView<Uzivatel>()

    ...
}

Uvedené premenné teraz môžeme nastaviť v Scene Builderi patričným komponentom v záložke Code ako fx:id.

Prepis metódy initialize()

V kontroléri máme od minule hotový konštruktor, ktorý meniť nebudeme. Budeme musieť ale prepísať metódu initialize(), v ktorej sprevádzkováme náš Spinner a nastavíme zobrazovanie detailu vybraného užívateľa:

override fun initialize(p0: URL?, p1: ResourceBundle?) {
    /**
     * Vytvoření ActionListener pro Spinner
     */
    val spinnerValueFactory = SpinnerValueFactory.IntegerSpinnerValueFactory(1, 100) // Vytvoření rozsahu hodnot pro Spinner
    spinnerValueFactory.value = 18 // Nastavení defaultní hodnoty
    novyUzivatelVek.valueFactory = spinnerValueFactory // Registrace SpinnerValueFactory pro Spinner

    // Vytvoření ActionListener pro ListView uzivateleList, při kliknutí na položku se zobrazí detaily uživatele
    uzivateleList.selectionModel.selectedItemProperty().addListener { _ ->
        val vybranyUzivatel =
            uzivateleList.selectionModel.selectedItem // Získání vybraného prvku v ListView

        if (vybranyUzivatel != null) {
            detailUzivatelJmenoLabel.text = vybranyUzivatel.jmeno // Vypsání jména uživatele
            detailUzivatelVekLabel.text = vybranyUzivatel.vek.toString() // Vypsání věku uživatele
            detailUzivatelDatumLabel.text =
                vybranyUzivatel.datumRegistrace.toString() // Vypsání datum registrace uživatele
        }
    }
}

V prvej časti nastavujeme pre Spinner vekové rozmedzie a defaultné zobrazenie hodnoty 18. Ďalej pridávame ActionListener, vďaka ktorému získame a vypíšeme meno, vek a dátum registrácie užívateľa.

Kód sme opodmienkovali pre prípad, že by nebol žiadny užívateľ vybraný (list by bol prázdny).

Obsluha tlačidiel

Teraz nám zostáva doplniť obsluhu našich tlačidiel.

Metóda ulozData()

Tlačidlo Uložiť máme pripravené z minulosti. V Scene Builder, v záložke Code voláme v políčku On Action metódu ulozData(). Z nej odstránime vytvorenie testovacích užívateľov a ponecháme len volanie metódy uloz() z triedy Databaze v try-catch bloku. Metóda bude teda vyzerať takto:

@FXML
private fun ulozData() {
    try {
        databaze!!.uloz()
    } catch (e: IOException) {
        println("ERROR: Databázi se nepodařilo uložit, zkontrolujte přístupová práva k souboru.")
        println(e.message)
    }
}

Metóda nacistData()

Podobne v Scene Builderi zaregistrujeme metódu nacistData() pri tlačidle Načítať. V kontroléri si metódu doplníme:

@FXML
private fun nacistData() {
    try {
        uzivateleList.items.clear()
        databaze!!.nacti()
        for (u in databaze!!.vratVsechny()) {
            uzivateleList.items.add(0, u) // Přidání nového záznamu Uživatele do ListView
        }
    } catch (e: IOException) {
        println("ERROR: Databázi se nepodařilo načíst, soubor zřejmě neexistuje.")
        println(e.message)
    }
}

Najprv vyprázdnime súčasný zoznam uzivateleList, potom zavoláme metódu nacti(). V cykle nakoniec metódy vratVsechny() získame zoznam užívateľov, ktorých postupne pridávame do vyprázdnenej kolekcie v kontajneri ScrollPane.

V reálnej aplikácii by sa načítanie vykonalo asi automaticky po spustení aplikácie a uložení po ukončení. Pre názornosť si to však ponecháme na tlačidlách.

Metóda vytvoritUzivatele()

Posledné sprevádzkováme tlačidlo pre pridanie nového užívateľa:

@FXML
private fun vytvoritUzivatele() {
    try {
        val jmeno: String = novyUzivatelJmeno.text   // Získání hodnoty z TextField novyUzivatelJmeno
        val vek: Int = novyUzivatelVek.value         // Získání hodnoty ze Spinner novyUzivatelVek

        /**
         * Nejdříve získáme hodnotu z DatePicker novyUzivatelDatumRegistrace,
         * Poté získáme den, měsíc a rok. Nakonec vytvoříme datum ve formátu "den'.'Měsíc'.'Rok"
         */
        val datePickerValue = novyUzivatelDatumRegistrace.value
        val den = datePickerValue.dayOfMonth.toString()
        val mesic = datePickerValue.monthValue.toString()
        val rok = datePickerValue.year.toString()
        val datum = "${den}.${mesic}.${rok}"

        val registrovan: LocalDate = LocalDate.parse(datum, DateTimeFormatter.ofPattern("d'.'M'.'y"))

        databaze!!.pridejUzivatele(jmeno, vek, registrovan) // Přidání nového záznamu do databáze

        val uzivatel = Uzivatel(jmeno, vek, registrovan)
        uzivateleList.items.add(0, uzivatel) // Přidání nového záznamu Uživatele do ListView
    } catch (e: IOException) {
        println(e.message)
    }
}

V tej najskôr získavame hodnoty položiek TextField, Spinner a DatePicker, dátum musíme naformátovať. Nakoniec pridáme užívateľa do databázy a získanými údajmi doplníme aj náš zoznam uzivateleList List.

Testovanie

Skúsime aplikáciu spustiť, načítať uložené dáta, pridať nového používateľa a všetko opäť uložiť:

Formulár databázy používateľov v CSV - Súbory a práce s nimi v Kotlin

Podobne by sme si mohli napísať aj mazanie používateľov.

V nasledujúcom cvičení, Riešené úlohy k 1.-5. lekciu práce so súbormi v Kotlin, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

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é 3x (41.23 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Kotlin

 

Predchádzajúci článok
Práca s textovými súbormi v Kotlin
Všetky články v sekcii
Súbory a práce s nimi v Kotlin
Preskočiť článok
(neodporúčame)
Riešené úlohy k 1.-5. lekciu práce so súbormi v Kotlin
Článok pre vás napísal Filip Studený
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
.
Aktivity