Closed SudoDios closed 4 months ago
Please add the source code.
ok i will
fun main (args : Array<String>) {
val app = Application("co.ex.test", ApplicationFlags.DEFAULT_FLAGS)
app.onActivate {
val window = ApplicationWindow(app).apply {
val scrolledWindow = ScrolledWindow().apply {
halign = Align.FILL
hexpand = true
}
val columnGen = makeColumn()
makeList().sortedBy { it.name }.forEach {
columnGen.first.append(it)
}
scrolledWindow.child = columnGen.second
child = scrolledWindow
}
window.present()
}
app.run(args)
}
private fun makeColumn () : Pair<ListStore, ColumnView>{
val nameFac = SignalListItemFactory().apply {
onSetup { obj ->
val row = obj as ColumnViewCell
row.child = Box(Orientation.HORIZONTAL,0).apply {
marginEnd = 8
marginBottom = 8
marginStart = 8
marginTop = 8
halign = Align.FILL
hexpand = true
val icon = Image.fromIconName("folder")
val label = Label("").apply {
marginStart = 12
halign = Align.START
hexpand = true
}
append(icon)
append(label)
}
}
onBind { obj ->
val row = obj as ColumnViewCell
val child = row.child as Box
val label = child.lastChild as Label
val model = obj.item as FileModel
label.label = model.name
}
}
val sizeFac = SignalListItemFactory().apply {
onSetup { obj ->
val row = obj as ColumnViewCell
row.child = Label("").apply {
marginEnd = 8
marginBottom = 8
marginStart = 8
marginTop = 8
halign = Align.START
hexpand = true
}
}
onBind { obj ->
val row = obj as ColumnViewCell
val child = row.child as Label
val model = obj.item as FileModel
child.label = model.size.formatToSizeFile()
}
}
val store = ListStore(FileModel.gType)
val columnView = ColumnView(MultiSelection(store)).apply {
halign = Align.FILL
hexpand = true
}
val nameColumn = ColumnViewColumn("Name",nameFac).apply {
expand = true
}
val sizeColumn = ColumnViewColumn("Size",sizeFac).apply {
fixedWidth = -1
}
columnView.appendColumn(nameColumn)
columnView.appendColumn(sizeColumn)
return Pair(store,columnView)
}
private fun makeList () : List<FileModel> {
val file = File("/your/home/dir")
val out = mutableListOf<FileModel>()
file.listFiles()?.forEach {
out.add(FileModel.create().apply {
name = it.name
size = it.length()
path = it.absolutePath
modified = it.lastModified()
})
}
return out
}
class FileModel(address: MemorySegment?) : GObject(address) {
companion object {
var gType: Type = Types.register<FileModel, ObjectClass>(FileModel::class.java)
fun create(): FileModel {
return newInstance(gType)
}
}
var name : String = ""
var path : String = ""
var size : Long = 0
var modified : Long = 0
}
This is an example of my code. To see the problem, select an item in list and move in the list with the up and down arrow keys on keyboard. After a few moments you will see the error
I can't reproduce the error, but I've seen a similar error before. I'm 99% sure it's related to garbage collection of the ListStore.
Looking at the main function and the app.onActivate
callback, you see that the ListStore is constructed (as a part of the columnGen
Pair) and then the window is presented. Past that point, the ListStore instance is not used anymore in the kotlin code. It's still used by native code, but the JVM is not aware of that. So when after a while the Garbage Collector runs, it destroys the ListStore instance.
If you put the ListStore (or in your case, the columnGen
variable) in a public field, the JVM should keep it alive, and the crash should disappear.
If you put the ListStore (or in your case, the
columnGen
variable) in a public field, the JVM should keep it alive, and the crash should disappear.
I will test this
@jwharm
Yes, it was done!
The problem was the JVM garbage collector. thank you 👍.
@SudoDios This turned out to be a bug in java-gi after all. It will be fixed in the next release.
@jwharm Really?!
How interesting.
Hi. I get this error :
C [libgio-2.0.so.0+0xcb1b5] g_list_model_get_n_items+0x25
when create a columnview with SelectionModel (single,multi). how fix it ?