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:
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ť:
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