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

4. diel - Práca s CSV súbormi v Kotlin - Uloženie objektov

V minulom dieli, Triedy pre prácu so súbormi v Kotlin , sme si ukázali, ako fungujú prístupové práva v operačných systémoch a ako sa vytvárajú inštancie tried Path a File.

V dnešnom Kotline tutoriále si vytvoríme formulárovú aplikáciu s databázou užívateľov, ktorá bude ukladať inštancie do textových súborov vo formáte CSV. Do CSV (ako Comma Separated Values) súborov ukladáme hodnoty oddelené čiarkou, prípadne bodkočiarkou. Každý riadok bude uchovávať hodnoty jedného používateľa.

JavaFX aplikácie

Na tvorbu formulára využijeme framework JavaFX. Jednoduchý formulár potom vďaka tomu budeme môcť naklikať v nástroji Scene Builder, ktorý za nás vygeneruje XML kód. Záujemca odkážem na kurz v sekcii Java, kde je síce ako vývojové prostredie použité NetBeans, ale postup v IntelliJ bude veľmi podobný.

Najprv si založíme v IntelliJ nový Kotlin projekt. V ďalšom okne vyberieme položku JavaFX a doplníme názov aplikácie. Programovacím jazykom bude Kotlin, správu balíčkov necháme na Maven, v políčku Group nastavujeme názov package, ktorý sme prepísali na itnetwork:

screenshot založenie projektu - Súbory a práce s nimi v Kotlin

Pokračujeme tlačidlom Next do ďalšieho okna, v ktorom nič meniť nebudeme a iba klikneme na tlačidlo Create.

IntelliJ nám vygenerovalo a otvorilo súbor pom.xml, jeden .fxml súbor pre vzhľad formulára, k nemu kontrolér a hlavnú triedu, všetko v štýle "Hello world" aplikácií.

Konfiguračný súbor pom.xml meniť nebudeme, ostatní si môžeme zmazať a postupne nahradiť vlastnými, prípadne si ich premenujeme a upravíme ich obsah.

Zamerajme sa ale najskôr na logickú vrstvu aplikácie.

Trieda Uzivatel

Poďme sa zhodnúť na tom, ako bude naša trieda používateľa vyzerať. Následne si ukážeme, ako jej inštancie do CSV uložíme.

Do vytvoreného projektu si pridáme triedu Uzivatel. U užívateľa budeme evidovať jeho meno, vek a dátum, kedy bol registrovaný. Konštruktor bude inštanciu inicializovať na základe týchto troch vlastností. Prepíšeme si metódu toString() tak, aby vrátila meno používateľa. Trieda teda bude vyzerať takto:

class Uzivatel(val jmeno: String, val vek: Int, val registrovan: LocalDate) {

    override fun toString(): String {
        return jmeno
    }
}

Naimportujeme si balíček java.time.LocalDate.

Trieda Databáze

Triedu užívateľa Uzivatel máme. Vytvoríme si aj triedu pre našu databázu, ktorú nazveme Databaze. Tá bude obsahovať kolekciu užívateľov, ktoré budeme ukladať do generického mutableListOf<Uzivatel>. Kolekcia bude privátna a pridávanie užívateľov (prípadne ich mazanie, vyhľadávanie a podobne) bude realizované verejnými metódami. Databáza bude obsahovať metódy na načítanie CSV súboru, a tiež na uloženie obsahu databázy do súboru. Pre meno súboru budeme mať privátny atribút soubor v triede Databaze.

Pridajme si teda k projektu triedu Databaze a predpíšme si do nej aj spomínané metódy:

class Databaze(soubor: Path) {
    private val uzivatele = mutableListOf<Uzivatel>()
    private val soubor: Path

    init {
        this.soubor = soubor
    }

    fun pridejUzivatele(jmeno: String, vek: Int, registrovan: LocalDate) {

    }

    fun vratVsechny(): List<Uzivatel> {

    }

    val model: MutableList<Uzivatel>


    @Throws(IOException::class)
    fun uloz() {

    }

    @Throws(IOException::class)
    fun nacti() {

    }
}

IntelliJ nám pri metóde vratVsechny() vyhubuje, pretože nevracia hodnotu, ale to si zatiaľ nebudeme všímať. Jednotlivé metódy vzápätí postupne naimplementujeme.

Metóda pridejUzivatele()

Poďme si ukázať, ako budú používatelia vo formáte CSV vyzerať. Každý riadok bude reprezentovať jedného používateľa. Vlastnosti užívateľa budú oddelené bodkočiarkami.

Napríklad užívateľ Pavel Slavík, ktorý má 22 rokov a zaregistroval sa 21.3.2000 by vo formáte CSV vyzeral takto:

Pavel Slavík;22;21.3.2000

Na prvý pohľad vidíme, že je súbor relatívne jednoducho čitateľný, aj keď nezasvätený sa môže len domnievať, čo je číslo 22 a na čo sa viaže ono dátum. V súbore môže byť samozrejme viac používateľov, teda viac riadkov.

Pridáme si metódu pridejUzivatele():

fun pridejUzivatele(jmeno: String, vek: Int, registrovan: LocalDate) {
    uzivatele.add(Uzivatel(jmeno, vek, registrovan))
}

Metóda getModel()

Ďalej si pridáme metódu model(), ktorá vráti kolekciu užívateľov:

val model: MutableList<Uzivatel>
    get() = uzivatele

Metóda vratVsechny()

Nakoniec si napíšeme metódu vratVsechny(), ktorá nám vráti kolekciu užívateľov List<Uzivatel>:

fun vratVsechny(): List<Uzivatel> {
    return uzivatele
}

Uloženie užívateľov do CSV

Teraz sa už dostávame k práci s CSV súborom. Preiterujeme náš list užívateľov a pre každého užívateľa vytvoríme premennú radek typu String, v ktorej budú jednotlivé vlastnosti užívateľa oddelené bodkočiarkou. Obsah premennej radek potom zapíšeme do súboru soubor:

@Throws(IOException::class)
fun uloz() {
    // Nejprve soubor vytvoříme, pokud již existuje tak jej vyprázdníme.
    Files.writeString(soubor, "", StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)
    for (u in vratVsechny()) {
        val radek: String =
            u.jmeno + ";" + u.vek + ";" + u.registrovan.toString() + System.lineSeparator()
        Files.writeString(soubor, radek, StandardOpenOption.APPEND)
    }
}

FXML formulár

Teraz budeme potrebovať vytvoriť samotný formulár. FXML súbory ukladáme v zložke main/ do podzložky resource/ a vnoreného balíčka. Na ten klikneme pravým a pridáme novú položku FXML File s názvom formular.fxml. Súbor si nájdeme vo svojom počítači a otvoríme ho v Scene Builderi.

Zatiaľ do neho vložíme kontajner VBox a do neho pridáme jeden Label a jeden Button. Kontajnera vo vlastnostiach nastavíme centrovanie na stred, av ponuke Controller vyplníme názov kontroléra: itnetwork.uzivatele.DatabazeKontroler. Položke Label vymažeme defaultný text a do fx:id vyplníme errorText, aby sa nám tu zobrazovali prípadné chybové hlášky. Button necháme zobrazovať text Ulož av ponuke Code vyplníme políčko On Action textom uloz. Tým zaistíme, že po kliknutí na tlačidlo bude zavolaná metóda uloz().

Máme hotovo, zmeny uložíme a vrátime sa do IntelliJ.

Kontroler DatabazeKontroler

Do projektu pridáme ďalší Kotlin triedu DatabazeKontroler. V tej vytvoríme privátny atribút databaze, do ktorého v konštruktore formulára uložíme novú inštanciu našej databázy:

class DatabazeKontroler {

    private var databaze: Databaze? = null

    init {
        try {
            val path = Path.of(System.getProperty("user.home"), "itnetwork", "uzivatele.csv")
            Files.createDirectories(path.getParent())
            databaze = Databaze(path)
        } catch (ex: IOException) {
            Logger.getLogger(DatabazeKontroler::class.java.name).log(Level.SEVERE, null, ex)

        }
    }
}

Pokiaľ vám IntelliJ podčiarkne posledný riadok, otvorte si súbor modules-info.java a doplňte doň riadok requires java.logging;, Ktorým zavoláte potrebný modul.

Ďalej si doplníme obsluhu formulára:

@FXML
private lateinit var errorText: Label

Najprv deklarujeme privátnu premennú errorText na zobrazenie chybových hlášok v našom Label komponente.

Ďalej doplníme obsluhu tlačidla Ulož, ktoré zaistí uloženie dvoch nižšie uvedených užívateľov. Toto riešenie je provizórne, aby sme mohli všetko vyskúšať, neskôr bude aplikácia vyzerať lepšie. Ďalej celú databázu metóda uloz() uloží do súboru:

@FXML
private fun uloz() {
    try {
        databaze!!.pridejUzivatele("Pavel Slavík", 22, LocalDate.of(2000, 3, 21))
        databaze!!.pridejUzivatele("Jan Novák", 31, LocalDate.of(2012, 10, 30))
        databaze!!.uloz()

    } catch (ex: IOException) {
        errorText.text = "Databázi se nepodařilo uložit, zkontrolujte přístupová práva k souboru."
        println("Databázi se nepodařilo uložit, zkontrolujte přístupová práva k souboru.")
    }
}

Položky na obsluhu FXML formulára nezabudneme označiť anotáciou @FXML.

Hlavná trieda

Na záver nám dnes zostáva doplniť hlavnú triedu s main() metódou. Jej kód bude dosť podobný vygenerovanej triede HelloApplication. My si triedu nazveme Main.kt a doplníme kód:

class Aplikace : Application() {
    override fun start(stage: Stage) {
        val fxmlLoader = FXMLLoader(Aplikace::class.java.getResource("formular.fxml"))
        val scene = Scene(fxmlLoader.load(), 320.0, 240.0)
        stage.title = "Databáze uživatelů!"
        stage.scene = scene
        stage.show()
    }
}

fun main() {
    Application.launch(Aplikace::class.java)
}

V hlavnej triede voláme pomocou fxmlLoader patričný formulár, nastavujeme jeho veľkosť a titulok a necháme všetko zobraziť.

Testovanie

Aplikáciu spustíme a klikneme na tlačidlo. Teraz otvoríme (napr. v NotePade) súbor uzivatele.csv a vidíme, že má nasledujúci obsah:

Pavel Slavík;22;21.3.2000
Jan Novák;31;30.10.2012

Všetko teda funguje, ako má:) .

V nasledujúcej lekcii, Práca s CSV súbormi v Kotlin - Načítanie objektov , dokončíme našu objektovú formulárovú aplikáciu s databázou používateľov s použitím textových súborov vo formáte CSV.


 

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

 

Predchádzajúci článok
Triedy pre prácu so 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)
Práca s CSV súbormi v Kotlin - Načítanie objektov
Článok pre vás napísal Filip Studený
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
.
Aktivity