i can't seem to get a DataGrid updated, when the m...
# tornadofx
i
i can't seem to get a DataGrid updated, when the maxCellsInRowProperty changes. it seems I should be able to call private fun updateItems() on DataGrid ...
b
do you pass observableList to DataGrid?
datagrid(observableList)
i
yes sure.
b
show how you add new elements, without just an example it's hard to help
i
datagrid<LabelContent> {
hgrow = Priority.ALWAYS
maxCellsInRowProperty.bind(data.columns)
data.columns.onChange {
DataGridSkin::class.java.getDeclaredMethod("updateItems").apply {
isAccessible = true
invoke(this@datagrid.skin)
}
}
itemsProperty.bind(data.data)
cellFragment<LabelContentFragment>()
}
this is the code I'm using right now. It works when i use the hack via reflection.
In the line itemsProperty.bind(data.data) I make sure, that the data for the grid is bound priopertly. data.data is defined in an ItemViewModel:
class LabelsDocumentDataModel : ItemViewModel<LabelsDocumentData>() {
// ... other stuff
val data = bind(LabelsDocumentData::data)
}
where in LabelsDocumentData data is defined as an observable list: val data = observableListOf<LabelContent>()
Let me know if I can somhow unwrap that better for you.
b
datagrid(data)
- does not work ?
cellFragment<LabelContentFragment>()
- you have your own fragment, you need to make sure that it can resize
updateItems
- called when updating your list
i
listview<T> can be called with a Property<ObservableList<T>> internally Listview then does just the same as i do: it binds the property to its itemProperty. datagrid can only be called with an ObservableList directly.
I do not want my fragment to resize.
b
axCellsInRowProperty.bind(data.columns)
data.columns.onChange {
DataGridSkin::class.java.getDeclaredMethod("updateItems").apply {
isAccessible = true
invoke(this@datagrid.skin)
}
}
- meaning then in this code? it's a reflection
i
yes, this is a reflection which is neededd, because i want to make the Datagrid update its layout
I want the maxCellsInRowProperty of the datagrid to take effect. For that problem I don't think that it would matter whether i have a fragment or just a simple Label to display the content of the data list.
so when i change maxCellsInRow from 2 to 3, it should display 3 columns instead of 2
what does happen without my reflection hack is the following:
1. maxCellsInRow is 2, i change it to 3
then nothing happens, the datagrid still displays 2 columns
then I change the content of the list (for example i add another item)
after that the datagrid does relayout, and everything is fine, i hvae 3 columns now
b
this code also needs to be shown, which does not work
i
well, probably i could make a minimal example ,...
because there is too much real-world application BS going on in my code, that isn't helpful to understand the problem
Omg ... this is horrible ... I cannot even add a simple observablelist to the datagrid ...
Now I got it - look at this:
class Test : View("Test") {
val myData = observableListOf<String>()
val maxCols = SimpleIntegerProperty(3)
override val root = vbox {
hbox {
button("add") {
action {
myData.add("str-${myData.size}")
}
}
spinner(1, 10, 3, 1, true, maxCols)
}
datagrid<String>(myData) {
maxCellsInRowProperty.bind(maxCols)
}
}
}
this is the most simple view that shows the problem i have.
b
t starts to work after redrawing, how to send a signal I have not yet found
I recommend to write issue https://github.com/edvin/tornadofx
👍 1
Copy code
class Test2 : View("Test") {
    val myData = observableListOf<String>()
    val maxCols = intProperty(2)

    override val root = vbox {
        hbox {
            button("add") {
                action {
                    myData.add("str-${myData.size}")
                }
            }
            spinner(1, 10, 3, 1, true, maxCols)
        }
        datagrid<String>(myData) {
            maxCellsInRowProperty.bind(maxCols)

            maxCols.addListener { _, old, new ->
                val oldValue = old.toInt()
                val newValue = new.toInt()
                println("$height:$width")
                if (oldValue < newValue) {
                    minWidth = width + 100.0 // not work scroll
//                    currentStage?.let { it.width += 100.0 }
                } else if (oldValue > newValue) {
                    minWidth = width - 100.0 // not work scroll
//                    currentStage?.let { it.width -= 100.0 }
                }
            }
        }
    }
}
maxCellsInRowProperty
- only sets the maximum possible amount, but does not determine the current, for this you need to change the size itself
i
thanks, but what does that have to do with the problem? I do not want to change the width of the stage or window at all
b
This is the width of the
datagrid
. I conducted an experiment and found out that even if you increase
maxCellsInRowProperty
and expand the window, the elements cannot be selected. This behavior resembles
FlowPane
.
it’s nothing more than a workaround
I comment a little bit in the code above, now updated
minWidth = width +- widthItem +- spaceItems