Skip to content

Instantly share code, notes, and snippets.

@altavir
Last active January 3, 2019 14:55
Show Gist options
  • Save altavir/2b8a60cf0dbdfaa132799ab0ca574d11 to your computer and use it in GitHub Desktop.
Save altavir/2b8a60cf0dbdfaa132799ab0ca574d11 to your computer and use it in GitHub Desktop.
A simple tornadofx table with column regex filter
import com.github.javafaker.Faker
import javafx.beans.InvalidationListener
import javafx.beans.binding.ListBinding
import javafx.beans.property.SimpleIntegerProperty
import javafx.collections.FXCollections
import javafx.collections.ObservableList
import javafx.geometry.Pos
import javafx.scene.layout.Priority
import tornadofx.*
import java.util.function.Predicate
import java.util.regex.PatternSyntaxException
class DemoApp : App(TableView::class)
fun main(args: Array<String>) {
launch<DemoApp>()
}
data class Entry(val name: String, val surname: String)
//Not a strict teacher, but demo-data generator
val faker = Faker()
class TableView : View("My View") {
val pageSize = 10
// all items
val items = FXCollections.observableArrayList<Entry>()
// list view after filter application
val filteredItems = items.filtered { true }
// the number of current page in paginator
val pageNumberProperty = SimpleIntegerProperty(0)
var pageNumber by pageNumberProperty
// content of the current page. Bound to both page number and
val page = object : ListBinding<Entry>() {
init {
bind(pageNumberProperty, filteredItems)
}
override fun computeValue(): ObservableList<Entry> {
val chunks = filteredItems.chunked(pageSize)
return if (chunks.isEmpty()) {
FXCollections.emptyObservableList()
} else {
val actualpage = pageNumberProperty.get().coerceAtMost(chunks.size - 1).coerceAtLeast(0)
chunks[actualpage].observable()
}
}
}
override val root = borderpane {
center {
tableview<Entry> {
//can't use binding as item storage so bind a copy
items.bind(page) { it }
readonlyColumn("Имя", Entry::name)
readonlyColumn("Фамилия", Entry::surname) {
//clearing the text
text = null
//replacing it with vertical alignment
graphic = vbox {
alignment = Pos.CENTER
label("Фамилия")
textfield {
promptText = "Фильтр"
hgrow = Priority.ALWAYS
textProperty().onChange {
try {
val regex = [email protected]()
pageNumber = 0
filteredItems.predicate = Predicate { entry ->
[email protected]() || entry.surname.matches(regex)
}
} catch (pse: PatternSyntaxException) {
// display validation error?
}
}
}
}
}
}
}
bottom {
pagination {
pageCountProperty().bind(filteredItems.sizeProperty.integerBinding{filteredItems.size / pageSize})
pageNumberProperty.bindBidirectional(currentPageIndexProperty())
}
}
}
init {
repeat(100) {
items.add(Entry(faker.name().firstName(), faker.name().lastName()))
}
}
}
@altavir
Copy link
Author

altavir commented Jan 3, 2019

Build file:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.3.11"
    id("org.openjfx.javafxplugin") version "0.0.5"
}

group = "ru.mipt.npm"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    compile(kotlin("stdlib-jdk8"))
    compile("no.tornado:tornadofx:1.7.17")
    compile(group= "com.github.javafaker", name= "javafaker", version = "0.16")
}

javafx {
    modules = listOf("javafx.controls")
}

tasks.withType<KotlinCompile> {
    kotlinOptions.jvmTarget = "1.8"
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment