NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Lekce 5 - Práce s CSV soubory v Kotlin - Načtení objektů

V minulé lekci, Práce s CSV soubory v Kotlin - Uložení objektů, jsme si vytvořili formulářovou aplikaci s databází uživatelů, která ukládá instance do textových souborů ve formátu CSV.

V dnešním Kotlin tutoriálu implementujeme do naší objektové formulářové aplikace načtení uživatelů z textového souboru ve formátu CSV.

Doplnění třídy Databaze

Do třídy Databaze si nejprve přidáme metodu pro načtení uživatelů.

Metoda nacti()

Kód metody je následující:

@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čátku metody kolekci uzivatele vyprázdníme zavoláním metody clear(). Soubor soubor budeme číst řádek po řádku v cyklu. Každý řádek rozdělíme metodou split(), které předáme oddělovač ;. Následně do kolekce uzivatele, pomocí metody pridejUzivatele(), přidáme objekt s rozdělenými hodnotami.

Prezentační vrstva aplikace

Nyní se pustíme do úpravy našeho formuláře. Do něj si připravíme nové formulářové prvky. Budeme chtít docílit následujícího vzhledu:

Ukázka konečné podoby formuláře - Soubory a práce s nimi v Kotlin

Otevřeme si formular.fxml ve Scene Builderu a do našeho kontejneru VBox vložíme další dva kontejnery typu Pane. První bude obsahovat dva popisky Label, kterým vyplníme text dle ukázky. Textu Databáze uživatelů zvětšíme písmo a nastavíme tučný font v záložce Properties.

Druhý Pane kontejner bude obsahovat tři vložené kontejnery. Jako první přidáme ScrollPane, ve kterém budeme zobrazovat seznam uživatelů typu ListView. Poté doplníme další Pane kontejner pro zobrazovaní detailu uživatele. Ten bude obsahovat sedm Label popisků - nadpis a popisek pro jméno, věk a datum registrace, vždy s odpovídajícím prázdným polem pro načtení detailu. Pod kontejner vložíme naše tlačítko Uložit a doplníme tlačítko pro načtení databáze.

Nakonec přidáme poslední Pane, který bude opět obsahovat popisky pro nadpis a údaje o uživateli, jehož chceme do databáze přidat. Pro odpovídající prázdná pole ale tentokrát zvolíme TextField pro zadání jména, Spinner pro výběr věku a DatePicker, který nám usnadní zadání data registrace. Pod kontejner nezapomeneme doplnit další tlačítko Přidat.

Doplnění obsluhy formuláře

Upravený formulář uložíme a v IntelliJ si otevřeme náš kontroler.

Deklarace FXML proměnných

V kontroleru nejprve deklarujeme nové proměnné pro seznam uživatelů a jednotlivé položky pro přidání uživatele a zobrazení 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é proměnné nyní můžeme nastavit ve Scene Builderu patřičným komponentám v záložce Code jako fx:id.

Přepis metody initialize()

V kontroleru máme od minule hotový konstruktor, který měnit nebudeme. Budeme muset ale přepsat metodu initialize(), v níž zprovozníme náš Spinner a nastavíme zobrazování detailu vybraného uživatele:

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 první části nastavujeme pro Spinner věkové rozmezí a defaultní zobrazení hodnoty 18. Dále přidáváme ActionListener, díky němuž získáme a vypíšeme jméno, věk a datum registrace uživatele.

Kód jsme opodmínkovali pro případ, že by nebyl žádný uživatel vybrán (list by byl prázdný).

Obsluha tlačítek

Nyní nám zbývá doplnit obsluhu našich tlačítek.

Metoda ulozData()

Tlačítko Uložit máme připravené z dřívějška. V Scene Builder, v záložce Code voláme v políčku On Action metodu ulozData(). Z ní odstraníme vytvoření testovacích uživatelů a ponecháme jen volání metody uloz() ze třídy Databaze v try-catch bloku. Metoda bude tedy vypadat 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)
    }
}

Metoda nacistData()

Obdobně ve Scene Builderu zaregistrujeme metodu nacistData() u tlačítka Načíst. V kontroleru si metodu 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)
    }
}

Nejprve vyprázdníme stávající seznam uzivateleList, poté zavoláme metodu nacti(). V cyklu nakonec metody vratVsechny() získáme seznam uživatelů, které postupně přidáváme do vyprázdněné kolekce v kontejneru ScrollPane.

V reálné aplikaci by se načtení vykonalo asi automaticky po spuštění aplikace a uložení po ukončení. Pro názornost si to však ponecháme na tlačítkách.

Metoda vytvoritUzivatele()

Poslední zprovozníme tlačítko pro přidání nového uživatele:

@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 té nejdříve získáváme hodnoty položek TextField, Spinner a DatePicker, datum musíme naformátovat. Nakonec přidáme uživatele do databáze a získanými údaji doplníme také náš seznam uzivateleList.

Testování

Zkusíme aplikaci spustit, načíst uložená data, přidat nového uživatele a vše opět uložit:

Formulář databáze uživatelů v CSV - Soubory a práce s nimi v Kotlin

Podobně bychom si mohli napsat i mazání uživatelů.

V následujícím cvičení, Řešené úlohy k 1.-5. lekci práce se soubory v Kotlin, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

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 3x (41.23 kB)
Aplikace je včetně zdrojových kódů v jazyce Kotlin

 

Předchozí článek
Práce s CSV soubory v Kotlin - Uložení objektů
Všechny články v sekci
Soubory a práce s nimi v Kotlin
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 1.-5. lekci práce se soubory v Kotlin
Článek pro vás napsal Filip Studený
Avatar
Uživatelské hodnocení:
2 hlasů
.
Aktivity