JavaFX Listview mit observableList

.daniel

Mitglied
Hallo,

in meiner ListView werden beim Scrollen die vorhandenen Einträge wiederholt anstatt die nächsten anzuzeigen.

MainView.kt
Code:
package app.view

import data.Fonts
import javafx.collections.FXCollections.observableArrayList
import javafx.scene.text.Font
import tornadofx.*
import java.io.File

class MainView : View("FontPerview") {
    val fonts: List<String>

    init {
        fonts = Fonts("""C:\Users\Daniel\Documents\plotter\#fonts""").getList()
    }

    override val root = listview(fonts.observable()) {
        cellFormat {
            graphic  = cache {
                form{
                    fieldset {
                        field {
                            label(File(it).name)
                        }
                        label("The quick brown fox jumps over the lazy dog") {
                            font = Font.loadFont(File(it).inputStream(), 32.0)
                        }

                        label("1234567890") {
                            font = Font.loadFont(File(it).inputStream(), 20.0)
                        }
                    }
                }
            }
        }
    }
}

data/Font.kt
Code:
package data

import java.io.File

class Fonts(dir:String){

    private var lst = mutableListOf<String>()

    init {
        File(dir).walk().filter {
            it.name.toLowerCase().endsWith(".ttf") or it.name.toLowerCase().endsWith(".otf")
        }.forEach { lst.add(it.toString()) }
    }

    fun getList():List<String> = lst
}

Sprache Kotlin
Modul TornadoFX


Kann mir bitte jemand erklären, wie ich die ListView / Liste richtig verwenden muss?
 
Kann es sein, weil du oben immer die selben Label vergibst? Bin zwar Kotlin-versiert (nicht in jedem Detail, z.B. Reflection und ein paar spezielle Konstrukte, aber sonst schon), aber mit TornadoFX hab ich (leider) noch nicht viel gemacht.
 
Wie meinst du das? Ich vergebe immer den Inhalt aus dem aktuellem Element.

Ich habe jetzt mal das Beispiel auf dem Buch zu TornadoFx kopiert aber auch hier klappt es nicht.

Code:
package app.view

import javafx.geometry.Pos
import javafx.scene.text.FontWeight
import tornadofx.*
import java.time.LocalDate
import java.time.Period

class MainView: View() {
    val persons = listOf(
            Person("John Marlow", LocalDate.of(2017,11,1)),
            Person("Ohn  Marlow", LocalDate.of(2016,10,2)),
            Person("Hn Marlow", LocalDate.of(2015,11,3)),
            Person("N Marlow", LocalDate.of(2014,11,4)),
            Person("Marlow", LocalDate.of(2013,11,5)),
            Person("Arlow", LocalDate.of(2012,11,6)),
            Person("Rlow", LocalDate.of(2011,11,7)),
            Person("Low", LocalDate.of(2010,11,8)),
            Person("Ow", LocalDate.of(2009,11,9)),
            Person("W", LocalDate.of(2008,11,10)),
            Person("Es", LocalDate.of(2007,11,12)),
            Person("Mes", LocalDate.of(2006,11,13)),
            Person("Ames", LocalDate.of(2005,11,14)),
            Person("James", LocalDate.of(2004,11,15)),
            Person("James Samantha", LocalDate.of(2003,11,16)),
            Person("Samantha James", LocalDate.of(2002,2,17))
    ).observable()

    override val root = listview(persons) {
        cellFormat {
            graphic = cache {
                form {
                    fieldset {
                        field("Name") {
                            label(it.name)
                        }
                        field("Birthday") {
                            label(it.birthday.toString())
                        }
                        label("${it.age} years old") {
                            alignment = Pos.CENTER_RIGHT
                            style {
                                fontSize = 22.px
                                fontWeight = FontWeight.BOLD
                            }
                        }
                    }
                }
            }
        }
    }
}

class Person(val name: String, val birthday: LocalDate) {
    val age: Int get() = Period.between(birthday, LocalDate.now()).years
}

Sobald gescrollt wird wird für index immer wieder bei 0 angefangen zu zählen.


Ich werde es gleich mal in JavaFx ohne TornadoFx probieren... Vielleicht klappt es dann
 
in JavaFx (ohne TornadoFx) funktioniert es mit eigener ListCell

Code:
import javafx.application.Application
import javafx.collections.FXCollections
import javafx.scene.Scene
import javafx.scene.control.Label
import javafx.scene.control.ListCell
import javafx.scene.control.ListView
import javafx.scene.layout.StackPane
import javafx.scene.layout.VBox
import javafx.scene.paint.Color
import javafx.scene.text.Font
import javafx.stage.Stage
import java.io.File

class KotlinTestFx: Application(){

    override fun start(primaryStage: Stage?) {
        if (primaryStage == null) return
        val root = StackPane()
        val scene = Scene(root, 640.0, 480.0, Color.WHITE)

        val observable = FXCollections.observableArrayList<String>()
        File("""C:\Users\Daniel\Documents\plotter\#fonts""").walk().filter { it.toString().toLowerCase().endsWith(".ttf") || it.toString().toLowerCase().endsWith(".otf") }.forEach { observable.add(it.toString()) }

        val listView = ListView(observable)
        listView.setCellFactory { FontListCell() }
        root.children.add(listView)

        primaryStage.scene = scene;
        primaryStage.title = "Hello Fx"
        primaryStage.show()

    }

    companion object {
        @JvmStatic fun main(args: Array<String>){
            launch(KotlinTestFx::class.java)
        }
    }
}

class FontListCell: ListCell<String>(){
    override fun updateItem(item: String?, empty: Boolean) {
        super.updateItem(item, empty)
        if(empty){
            text = null
            graphic = null
        }
        else{
            text = null
            val hbox = VBox()

            val file = File(item)
            val labelName = Label(file.name)
            val font = Font.loadFont(file.inputStream(), 32.0)
            val labelExText = Label("the quick brown fox jumps over the lazy dog")
            if (font != null) labelExText.font = font
            val labelExNum = Label("0123456789")
            if (font != null) labelExNum.font = font

            hbox.children.add(labelName)
            hbox.children.add(labelExText)
            hbox.children.add(labelExNum)

            graphic = hbox
        }
    }
}
 
Hast du mal den Edvin Syse direkt gefragt? Z.B auf Twitter - @edvinsyse ? Die meisten OpenSourcer antworten ziemlich schnell...
Ich hab das Beispiel gefunden, was du wohl als Vorlage verwendet hast - https://github.com/edvin/tornadofx-guide/blob/master/part2/Advanced Data Controls.md - deine Implementation sieht für mich korrekt aus.

Sorry, aber mehr kann ich dir nicht weiterhelfen, fürchte ich.

Btw: Vergiss meine ursprüngliche Aussage, ich hab erst heute gesehen, dass ich das Format nur einfach nicht verstanden hatte... :-/
 

Neue Themen


Zurück
Oben