K
10/16/2023, 11:06 AMjava.awt.FileDialog
at the same time?
For example, keep a FileDialog
open, and open another one later, JVM will crashes if the first one close first.
java.awt.EventQueue.invokeLater {
val dialog1 = java.awt.FileDialog(window)
dialog1.isVisible = true
}
delay(1000)
java.awt.EventQueue.invokeLater {
val dialog2 = java.awt.FileDialog(window)
dialog2.isVisible = true
}
Alexander Maryanovsky
10/16/2023, 12:09 PMK
10/16/2023, 12:17 PMAlexander Maryanovsky
10/16/2023, 12:41 PMK
10/16/2023, 12:48 PMfileDialog.setVisible(Boolean)
is a blocking call.Alexander Maryanovsky
10/16/2023, 12:49 PMK
10/16/2023, 12:50 PMCan you make it non-modal?Possible a right way to do non-modal? but no luck.
val d = java.awt.FileDialog(null as java.awt.Frame?)
d.isModal = false
d.isVisible = true
Alexander Maryanovsky
10/16/2023, 1:07 PMK
10/16/2023, 1:08 PM@Composable
private fun FileDialog(
title: String? = "Choose a file",
parent: Frame? = null,
onCloseRequest: (result: String?) -> Unit
) = AwtWindow(
create = {
object : java.awt.FileDialog(parent, title) {
override fun setVisible(value: Boolean) {
super.setVisible(value)
if (value) {
onCloseRequest(file)
}
}
}
},
dispose = java.awt.FileDialog::dispose
)
@JvmStatic
fun main(args: Array<String>) {
application {
Window(onCloseRequest = ::exitApplication) {
MaterialTheme {
Surface {
var isOpen by remember { mutableStateOf(false) }
Column {
// uncomment for recompose.
// val num by produceState(0) {
// var i = 1
// while (true) {
// delay(1000)
// value = i++
// }
// }
// Text(text = "num = $num") //test if UI thread blocking.
Button(
onClick = { isOpen = !isOpen },
) {
Text("FileDialog isOpen = $isOpen")
}
}
if (isOpen) {
println("recompose!!")
FileDialog(
title = "1",
parent = window,
onCloseRequest = { isOpen = false }
)
FileDialog(
title = "2",
parent = window,
onCloseRequest = { isOpen = false }
)
}
}
}
}
}
}
AwtWindow
pointed out this problem already. UI freezing due to the blocking call inside it, so I can't press two button for two different FileDialog.Alexander Maryanovsky
10/16/2023, 1:43 PMK
10/16/2023, 1:43 PMWhat’s the issue? Seems to work ok for me.Close "1" then close "2", JVM crash.
Alexander Maryanovsky
10/16/2023, 1:45 PMK
10/16/2023, 1:45 PMdhia chemingui
10/16/2023, 1:45 PMK
10/16/2023, 1:47 PMAlexander Maryanovsky
10/16/2023, 1:47 PMK
10/16/2023, 1:48 PMparent = null,
?Alexander Maryanovsky
10/16/2023, 1:50 PMK
10/16/2023, 1:55 PMuncomment for recompose
for test.Alexander Maryanovsky
10/16/2023, 1:57 PMK
10/16/2023, 1:59 PMAlexander Maryanovsky
10/16/2023, 2:00 PMK
10/16/2023, 2:16 PMprivate val lock = Any()
fun java.awt.Window.blockingVisible(value: Boolean = true) {
synchronized(lock) {
println("inside lock")
isVisible = value
}
println("outside lock ")
}
inside lock
inside lock
outside lock
dialog2 closed
outside lock
dialog1 closedAlexander Maryanovsky
10/16/2023, 2:23 PMK
10/16/2023, 2:34 PMAlexander Maryanovsky
10/16/2023, 2:46 PMdhia chemingui
10/16/2023, 2:56 PMK
10/16/2023, 3:59 PMHere it’s the same threadSeems not the same thread to me. That's why when one setVisible blocking, other one setVisible get called.
private val mainSingleDispatcher = MainUIDispatcher.limitedParallelism(1)
suspend fun java.awt.Window.blockingSetVisible(value: Boolean = true) {
withContext(mainSingleDispatcher) {
isVisible = value
}
}
Now I can fix it by this code. Always limit only one dialog to open.Alexander Maryanovsky
10/16/2023, 4:02 PMK
10/16/2023, 4:22 PMMichael Paus
10/17/2023, 9:06 AMK
10/17/2023, 10:48 AMAlexander Maryanovsky
10/17/2023, 10:49 AM