我如何重构视图,以允许过滤绑定到tornadofx应用程序内的observableArrayList的项目

我从gradle hello-world例子开始,findhttps://github.com:JetBrains/kotlin-examples.git,并将其修改为使用TornadoFX。

这是一个显示项目列表的应用程序。 您可以添加到列表中, RequestView将自动显示所有项目。

我有它的工作,以便存储的项目绑定到一个observableArrayList但我现在要实现一个使用TextView在底部的filter。 但是,我很难理解这是否意味着我应该创建一个新的列表,这是在RequestView内部进行管理的,并且从中进行过滤,或者如何执行。

 package demo import javafx.collections.FXCollections import javafx.geometry.Pos import javafx.scene.control.TextField import javafx.scene.layout.VBox import javafx.scene.text.FontWeight import tornadofx.* class helloWorldApp : App(HelloWorld::class) { } class HelloWorld : View() { override val root = VBox() var requestView: RequestView by singleAssign() var filterField: TextField by singleAssign() init { with(root) { requestView = RequestView() this += requestView filterField = TextField() this += filterField } requestView.items.add("Hi there") requestView.items.add("Another one") } } class RequestView() : View() { var items = FXCollections.observableArrayList() override val root = listview(items) { cellFormat { graphic = cache { form { fieldset { label(it) { alignment = Pos.CENTER_LEFT style { fontSize = 15.px fontWeight = FontWeight.BOLD } } } } } } } } 

这里是build.gradle文件,以防万一它有帮助。

 buildscript { ext.kotlin_version = '1.1.2' repositories { mavenCentral() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } apply plugin: 'kotlin' apply plugin: 'application' mainClassName = 'demo.helloWorldApp' defaultTasks 'run' repositories { mavenCentral() } tasks.compileKotlin.kotlinOptions.jvmTarget = "1.8" dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" testCompile 'junit:junit:4.11' testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" compile 'no.tornado:tornadofx:1.7.10' } task wrapper(type: Wrapper) { gradleVersion = "2.7" } 

您应该使用SortedFilteredList封装ObservableList并接受用于区分条目的谓词。

在你的两个视图之间有一个不幸的耦合,所以你应该考虑发射一个事件,但这是一个工作的解决方案,只需对你的示例进行很少的修改。 我确实将数据移动到了一个模型中,并清理了ui代码,以及摆脱了singleAssign语句,并将一些最佳实践应用于构建者:)

正如你所看到的, SortedFilteredList有一个filterWhen函数,只要textProperty()发生变化就会被调用。

 class HelloWorldApp : App(HelloWorld::class) class HelloWorld : View() { val requestView: RequestView by inject() override val root = vbox { add(requestView) textfield { promptText = "Filter" requestView.data.filterWhen(textProperty()) { query, item -> item.contains(query, ignoreCase = true) } } } } class ItemsModel : ViewModel() { val items = FXCollections.observableArrayList() fun addItem(item: String) = items.add(item) init { addItem("Hi there") addItem("Another one") } } class RequestView() : View() { val model: ItemsModel by inject() val data = SortedFilteredList(model.items) override val root = listview(data) { cellFormat { graphic = cache { form { fieldset { label(it) { alignment = Pos.CENTER_LEFT style { fontSize = 15.px fontWeight = FontWeight.BOLD } } } } } } } }