Skip to content

Commit 2cae596

Browse files
committed
Backport (as much as possible) edvin/tornadofx2#40
1 parent bb4bfe2 commit 2cae596

File tree

2 files changed

+40
-47
lines changed

2 files changed

+40
-47
lines changed

src/main/java/tornadofx/Component.kt

+37-45
Original file line numberDiff line numberDiff line change
@@ -529,61 +529,53 @@ abstract class UIComponent(viewTitle: String? = "", icon: Node? = null) : Compon
529529
properties["tornadofx.closeable"] = SimpleBooleanProperty(false)
530530
}
531531

532-
private val rootParentChangeListener: ChangeListener<Parent>
533-
get() {
534-
val key = "tornadofx.rootParentChangeListener"
535-
if (properties[key] == null) {
536-
properties[key] = ChangeListener<Parent> { _, oldParent, newParent ->
537-
if (modalStage != null) return@ChangeListener
538-
if (newParent == null && oldParent != null && isDocked) callOnUndock()
539-
if (newParent != null && newParent != oldParent && !isDocked) {
540-
callOnDock()
541-
// Call `onTabSelected` if/when we are connected to a Tab and it's selected
542-
// Note that this only works for builder constructed tabpanes
543-
owningTab?.let {
544-
it.selectedProperty()?.onChange { if (it) onTabSelected() }
545-
if (it.isSelected) onTabSelected()
546-
}
547-
}
532+
private val rootParentChangeListener: ChangeListener<Parent> by lazy {
533+
ChangeListener<Parent> { _, oldParent, newParent ->
534+
if (modalStage != null) return@ChangeListener
535+
if (newParent == null && oldParent != null && isDocked) callOnUndock()
536+
if (newParent != null && newParent != oldParent && !isDocked) {
537+
callOnDock()
538+
// Call `onTabSelected` if/when we are connected to a Tab and it's selected
539+
// Note that this only works for builder constructed tabpanes
540+
owningTab?.let {
541+
it.selectedProperty()?.onChange { if (it) onTabSelected() }
542+
if (it.isSelected) onTabSelected()
548543
}
549544
}
550-
return properties[key] as ChangeListener<Parent>
551545
}
546+
}
552547

553-
private val rootSceneChangeListener: ChangeListener<Scene>
554-
get() {
555-
val key = "tornadofx.rootSceneChangeListener"
556-
if (properties[key] == null) {
557-
properties[key] = ChangeListener<Scene> { _, oldParent, newParent ->
558-
if (modalStage != null || root.parent != null) return@ChangeListener
559-
if (newParent == null && oldParent != null && isDocked) callOnUndock()
560-
if (newParent != null && newParent != oldParent && !isDocked) {
561-
// Calls dock or undock when window opens or closes
562-
newParent.windowProperty().onChangeOnce {
563-
it?.showingProperty()?.addListener(rootSceneWindowShowingPropertyChangeListener)
564-
}
565-
callOnDock()
566-
}
548+
private val rootSceneChangeListener: ChangeListener<Scene> by lazy {
549+
ChangeListener<Scene> { _, oldParent, newParent ->
550+
val key = "tornadofx.rootSceneWindowPropertyChangeListener"
551+
552+
if (modalStage != null || root.parent != null) return@ChangeListener
553+
if (newParent == null && oldParent != null && isDocked) {
554+
(properties[key] as? ChangeListener<Window>)?.run {
555+
oldParent.windowProperty().removeListener(this)
567556
}
557+
callOnUndock()
558+
}
559+
if (newParent != null && newParent != oldParent && !isDocked) {
560+
// Calls dock or undock when window opens or closes
561+
properties[key] = newParent.windowProperty().onChangeOnce {
562+
it?.showingProperty()?.addListener(rootSceneWindowShowingPropertyChangeListener)
563+
}
564+
callOnDock()
568565
}
569-
return properties[key] as ChangeListener<Scene>
570566
}
567+
}
571568

572-
private val rootSceneWindowShowingPropertyChangeListener: ChangeListener<Boolean>
573-
get() {
574-
val key = "tornadofx.rootSceneWindowShowingPropertyChangeListener"
575-
if (properties[key] == null) {
576-
properties[key] = ChangeListener<Boolean> { property, oldValue, newValue ->
577-
if (!isInitialized) {
578-
property.removeListener(rootSceneWindowShowingPropertyChangeListener)
579-
return@ChangeListener
580-
}
581-
if (!newValue && isDocked) callOnUndock()
582-
if (newValue && !isDocked) callOnDock()
583-
}
569+
private val rootSceneWindowShowingPropertyChangeListener: ChangeListener<Boolean> by lazy {
570+
ChangeListener<Boolean> { property, _, newValue ->
571+
if (!isInitialized) {
572+
property.removeListener(rootSceneWindowShowingPropertyChangeListener)
573+
return@ChangeListener
584574
}
585-
return properties[key] as ChangeListener<Boolean>
575+
if (!newValue && isDocked) callOnUndock()
576+
if (newValue && !isDocked) callOnDock()
586577
}
578+
}
587579

588580
internal fun init() {
589581
if (isInitialized) return

src/main/java/tornadofx/Lib.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ inline fun <T> ChangeListener(crossinline listener: (observable: ObservableValue
233233
* Listen for changes to this observable. Optionally only listen x times.
234234
* The lambda receives the changed value when the change occurs, which may be null,
235235
*/
236-
fun <T> ObservableValue<T>.onChangeTimes(times: Int, op: (T?) -> Unit) {
236+
fun <T> ObservableValue<T>.onChangeTimes(times: Int, op: (T?) -> Unit): ChangeListener<T> {
237237
var counter = 0
238238
val listener = object : ChangeListener<T> {
239239
override fun changed(observable: ObservableValue<out T>?, oldValue: T, newValue: T) {
@@ -244,9 +244,10 @@ fun <T> ObservableValue<T>.onChangeTimes(times: Int, op: (T?) -> Unit) {
244244
}
245245
}
246246
addListener(listener)
247+
return listener
247248
}
248249

249-
fun <T> ObservableValue<T>.onChangeOnce(op: (T?) -> Unit) = onChangeTimes(1, op)
250+
fun <T> ObservableValue<T>.onChangeOnce(op: (T?) -> Unit): ChangeListener<T> = onChangeTimes(1, op)
250251

251252
fun <T> ObservableValue<T>.onChange(op: (T?) -> Unit) = apply { addListener { _, _, newValue -> op(newValue) } }
252253
fun ObservableBooleanValue.onChange(op: (Boolean) -> Unit) = apply { addListener { _, _, new -> op(new ?: false) } }

0 commit comments

Comments
 (0)