https://kotlinlang.org logo
i

iari

10/27/2019, 7:42 AM
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

Bogdan

10/27/2019, 7:46 AM
do you pass observableList to DataGrid?
datagrid(observableList)
i

iari

10/27/2019, 8:04 AM
yes sure.
b

Bogdan

10/27/2019, 8:06 AM
show how you add new elements, without just an example it's hard to help
i

iari

10/27/2019, 8:08 AM
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

Bogdan

10/27/2019, 8:25 AM
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

iari

10/27/2019, 8:40 AM
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

Bogdan

10/27/2019, 8:43 AM
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

iari

10/27/2019, 8:43 AM
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

Bogdan

10/27/2019, 8:47 AM
this code also needs to be shown, which does not work
i

iari

10/27/2019, 8:47 AM
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

Bogdan

10/27/2019, 9:11 AM
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

iari

10/27/2019, 10:02 AM
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

Bogdan

10/27/2019, 10:06 AM
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
3 Views