Skip to content

Instantly share code, notes, and snippets.

@deggers
Created April 17, 2020 12:36
Show Gist options
  • Save deggers/2943c1af62de0abe72c66e9d1ca55583 to your computer and use it in GitHub Desktop.
Save deggers/2943c1af62de0abe72c66e9d1ca55583 to your computer and use it in GitHub Desktop.
import javafx.beans.property.ObjectProperty
import javafx.beans.property.SimpleListProperty
import javafx.collections.ObservableList
import javafx.geometry.Pos
import javafx.scene.control.TreeItem
import javafx.scene.layout.HBox
import tornadofx.*
class MinimalExample : App(MyTreeView::class)
// model
class MyItemModel(name: String = "model", group: MyGroupModel = MyGroupModel()) {
var name: String by property(name)
fun nameProperty(): ObjectProperty<String> = getProperty(MyItemModel::name)
var group: MyGroupModel by property(group)
fun groupProperty(): ObjectProperty<MyGroupModel> = getProperty(MyItemModel::group)
}
// model view model
class MyItemViewModel(model: MyItemModel = MyItemModel()) : ItemViewModel<MyItemModel>(model) {
val name = bind(MyItemModel::nameProperty, autocommit = true)
val group = bind(MyItemModel::groupProperty, autocommit = true)
}
//group model
class MyGroupModel(name: String = "group") {
var name: String by property(name)
fun nameProperty(): ObjectProperty<String> = getProperty(MyGroupModel::name)
}
//group view model
class MyGroupViewModel(model: MyGroupModel = MyGroupModel()) : ItemViewModel<MyGroupModel>(model) {
val name = bind(MyGroupModel::nameProperty, autocommit = true)
}
// main model
class MainModel {
private fun itemListProperty(): SimpleListProperty<MyItemModel> = SimpleListProperty(observableListOf()
{ model: MyItemModel -> arrayOf(model.nameProperty(), model.groupProperty()) })
val itemList: ObservableList<MyItemModel> by itemListProperty()
private fun groupListProperty(): SimpleListProperty<MyGroupModel> =
SimpleListProperty(observableListOf<MyGroupModel>()
{ model -> arrayOf(model.nameProperty()) })
val groupList: ObservableList<MyGroupModel> by groupListProperty()
}
// main model view model
class MainViewModel(model: MainModel = MainModel()) : ItemViewModel<MainModel>(model) {
val itemList = bind(MainModel::itemList, autocommit = true)
val groupList = bind(MainModel::groupList, autocommit = true)
}
class MyTreeView : View() {
val mainViewModel: MainViewModel by inject()
val itemViewModel: MyItemViewModel by inject()
val groupViewModel: MyGroupViewModel by inject()
val groups = mainViewModel.groupList.value.sorted(Comparator.comparing<MyGroupModel, String> { it.name })
val itemList = mainViewModel.itemList.value
init {
val group1 = MyGroupModel("a")
val group2 = MyGroupModel("b")
mainViewModel.groupList.value.addAll(group1, group2)
val item1 = MyItemModel("a", group1)
val item3 = MyItemModel("c", group1)
val item2 = MyItemModel("b", group1)
mainViewModel.itemList.value.addAll(item1, item2, item3)
val item5 = MyItemModel("b", group2)
val item6 = MyItemModel("c", group2)
val item4 = MyItemModel("a", group2)
mainViewModel.itemList.value.addAll(item4, item5, item6)
}
override val root = vbox {
treeview<Any> {
root = TreeItem(MyGroupModel("root"))
isShowRoot = false
cellFormat {
graphic = when (val model = it) {
is MyItemModel -> HBox().apply {
alignment = Pos.CENTER
label(model.name)
}
is MyGroupModel -> HBox().apply {
label(model.name)
}
else -> throw IllegalArgumentException("Invalid value type")
}
}
val factory: (TreeItem<Any>) -> Iterable<Any>? = { parent ->
val value = parent.value
when {
parent == root -> groups
value is MyGroupModel -> {
SortedFilteredList(itemList, { it.group == value }).sortedItems.also {
it.comparator = Comparator.comparing<MyItemModel, String> { it.name.decapitalize() }
}
}
else -> null
}
}
populate(childFactory = factory)
itemViewModel.rebindOnChange(this.selectionModel.selectedItemProperty()) {
if (it?.value is MyItemModel) {
item = it.value as MyItemModel
}
}
groupViewModel.rebindOnChange(this.selectionModel.selectedItemProperty()) {
if (it?.value is MyGroupModel) {
item = it.value as MyGroupModel
}
}
}
form {
fieldset("Edit item") {
field("Name") {
textfield(itemViewModel.name) {
}
}
field("Group") {
combobox(itemViewModel.group, groups) {
cellFormat {
text = it.name
}
}
}
}
}
form {
fieldset("Edit group") {
field("Name") {
textfield(groupViewModel.name) {
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment