【问题标题】:unidirectional bind and set with conversion in JavaFXJavaFX中的单向绑定和转换设置
【发布时间】:2026-01-06 08:05:02
【问题描述】:

我最近在我的 JavaFX 应用程序中编写了这样的函数:

public static <T1, T2> void bindAndSet(ReadOnlyProperty<T1> sourceProperty, Property<T2> targetProperty, Function<T1, T2> converter) {
    sourceProperty.addListener(new WeakChangeListener<>((obs, oldVal, newVal) -> targetProperty.setValue(converter.apply(newVal))));
    targetProperty.setValue(converter.apply(sourceProperty.getValue()));
}

这是带有转换和设置初始值的单向绑定。 我在 JavaFX 方面的经验很少,但它似乎应该是使用绑定的应用程序中相当常见的部分。 Property#bind 似乎几乎没用。它不允许转换类型并且通过检查源代码它不设置初始值。

是否有提供此类功能的方法(或 2 个)? 或者我可能以错误的方式使用 JavaFX API?

【问题讨论】:

  • 如何扩展 ObjectBinding 并在 computeValue() 中应用转换器?
  • @SergeyGrinev 我不能 100% 确定它的外观,但它似乎比我的解决方案要大,尽管分析这个我发现 Bindings 类看起来很有趣但通常不安全
  • 到底有什么问题?顺便说一句:weakListener 不会立即被 gc'ed 吗?另外:_它没有设置初始值_ - 为什么要设置?绑定后,它的值 sourceValue。对property.bind 时的通知不完全确定.. 在绑定方面做了一些工作,请参阅openjfx 邮件列表(和repo)
  • 目前,属性会在绑定时发出通知 - 所以这里真的看不到问题。
  • @kleopatra 在我的情况下,侦听器在 UI 中,因此只要显示(或可访问)它就不会被 GC,不设置初始值 UI 组件看起来不像他们知道 sourceValue你提到了

标签: java javafx


【解决方案1】:

你可以使用Bindings.createObjectBinding():

targetProperty.bind(Bindings.createObjectBinding(
        () -> converter.apply(sourceProperty.get()), sourceProperty));

【讨论】:

  • 不错!它比我的解决方案小,唯一的缺点 - 它更容易出错(但风险很小)。它还支持更多用例。谢谢!
  • @Sankozi 我同意,它并不完美,但它很短。很高兴它有帮助;)