edvin / tornadofx

Lightweight JavaFX Framework for Kotlin
Apache License 2.0
3.68k stars 272 forks source link

whenDockedOnce & whenUndockedOnce don't work #1026

Open ykrasik opened 5 years ago

ykrasik commented 5 years ago

https://github.com/edvin/tornadofx/blob/master/src/main/java/tornadofx/Component.kt#L1261

The implementation looks wrong - the listener which is added to the onDockListeners is a lambda which wraps the original listener, but inside the lambda the code tries to remove the original listener (which quietly returns false). The result - the listener gets called on each dock.

edvin commented 5 years ago

Thanks for reporting. I've committed a fix now. I wanted to find a way to avoid the intermediary wrapped variable, but was unable to find a smoother way than this:

fun <U : UIComponent> U.whenDockedOnce(listener: (U) -> Unit) {
    if (onDockListeners == null) onDockListeners = mutableListOf()
    var wrapped: (U) -> Unit = {}
    wrapped = {
        runLater {
            onDockListeners!!.remove(wrapped)
        }
        listener(it)
    }
    whenDocked(wrapped)
}

The runLater is needed to avoid removing the listener from the list as it is being iterated over.

ykrasik commented 5 years ago

Yeah I couldn't figure out any nicer way either, seems like there's no way to reference the this of a lambda.