从 ScalaFX 中的 属性 移除监听器

Removing listeners from property in ScalaFX

我正在努力从 ScalaFX 的 Property 中删除一个事件侦听器。

简化示例

import scalafx.Includes._

object ListenerApp {

  val prop = DoubleProperty(0)

  val listener = (source, oldValue, newVal) => {
    println("Listener working, and the value is " + newVal)
  }

  def main(args: Array[String]) = {
    prop.addListener(listener)
    prop.value = 1
    prop.removeListener(listener)
    prop.value = 2
  }

}

结果与预期不符:

Listener working, and the value is 1.0
Listener working, and the value is 2.0

我在 JavaFX 中看到过类似的代码,但我的改编可能是错误的。

附加信息

我很困惑我的方法是否有错误,因为 unbindBidirectional() 也发生了类似的事情,或者这可能是一个错误,因为这个功能可能没有被广泛使用并且没有人注意到。

尝试使用调试器访问 delegate 中的侦听器,但未显示任何字段。

为什么我还需要这个

我有一个显示一些 insideProp: Property 的视图,它是另一个 outsideProp: ObjectProperty[T] 中对象 content: T 的成员。

但是我不想显示特定的 contentinsideProp 或者 outsideProp 中的任何内容。为此,我需要一个可移动绑定或一个可移动事件侦听器,因为视图只能由 outsideProp.

的当前内容修改

我很乐意为每个 content 创建一个新的 "immutable" 视图,但是从经验来看 JavaFX 并不是真正为这种行为而构建的,而且还存在内存问题泄漏。

如果有人指出我做错了什么,我将不胜感激。

添加监听器

在 ScalaFX 中添加 属性 监听器的惯用方法是使用 onChange方法:

val prop = DoubleProperty(0)

prop.onChange { (source, oldValue, newValue) =>
  println(s"Property $source changed value from $oldValue to $newValue")
}

如果你只想要新值你可以忽略前两个参数:

prop.onChange { (_, _, newValue) =>
  println(s"Property changed value to $newValue")
}

删除监听器

订阅句柄可让您删除侦听器。 为添加到 属性 的每个侦听器创建一个订阅。 当您不再需要收听时,您 "cancel" 订阅:

val prop = DoubleProperty(0)

val subscription = prop.onChange { (_, _, newValue) =>
             println(s"Property changed value to $newValue")
           }

prop.value = 1
subscription.cancel()

// Listener will not be notified about this change
prop.value = 2