当javafx中的父属性更改时,清理绑定并更改嵌套属性上的侦听器

几何

我有一个带有SimpleXXXXProperty属性的模型类Javafx GUI元素使用绑定或更改侦听器进行更新,例如

textField.textProperty().bind(myModel.myModelStatus());

要么

myModel.myModelStatus().addListener((obj,oldv.newv) -> { update here });

当模型类的实例更改时,我将重新绑定控件并再次添加侦听器。但是,通过内存使用,我可以看到旧模型仍保留在内存中。

我该怎么做才能删除对模型的所有引用,以便可以对其进行清理?

  • 取消绑定,然后再次绑定
  • 删除监听器

当父属性更改时,是否有更自动的方法来更新嵌套属性上的绑定和侦听器?

isnot2bad

要撤消模型的绑定(包括侦听器)时要考虑的要点:

  • 再次绑定p1.bind(p2)同一属性(例如p1.bind(p3))时,无方向绑定()会自动解除绑定,但是显式地进行绑定()也无害p1.unbind()
  • 双向绑定(p1.bindBidirectional(p2)Bindings.bindBidirectional(p1, p2))必须明确地解除绑定(p1.unbindBidirectional(p2)Bindings.unbindBidirectional(p1, p2))。
  • 侦听器必须未注册(prop.removeListener(l))。

第三是棘手的部分,因为侦听器通常实现为lambda表达式或方法引用。(!)不幸的是,lambda表达式以及方法的引用是不是常数:

// lambdas are not constant
InvalidationListener l1 = obs -> {};
InvalidationListener l2 = obs -> {};

assert l1 != l2; // they are NOT identical!

嗯,这对于lambda来说可能是显而易见的,但是对于方法引用也是如此,这确实很烦人:

// method references are not constant
Runnable runnable1 = this::anyMethod;
Runnable runnable2 = this::anyMethod;

assert runnable1 != runnable2; // they are NOT identical!

这意味着,如果您想取消注册lambda表达式或简单的方法引用,则不能将其注册为侦听器:

// if you register listeners on a property like that...
label.textProperty().addListener(obs -> System.out.println(obs));
label.textProperty().addListener(this::handleLabelInvalid);

// ...these calls WON'T remove them due to the inequality shown above!
label.textProperty().removeListener(obs -> System.out.println(obs));
label.textProperty().removeListener(this::handleLabelInvalid);

您必须自己存储对lambda表达式或方法引用的引用。我通常使用final字段:

public class MyClass {
    // store references for adding/removal
    private final InvalidationListener l1 = this::handleLabelInvalid;
    private final InvalidationListener l2 = obs -> System.out.println(obs);

    ...

    public void bind() {
        label.textProperty().addListener(l1);
        label.textProperty().addListener(l2);
    }

    public void unbind() {
        label.textProperty().removeListener(l1);
        label.textProperty().removeListener(l2);
    }

    private void handleLabelInvalid(Observable observable) { ... }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

JavaFX的TextField的值更改侦听器

更改时如何为jtexfield添加侦听器?

使用属性更改侦听器更新挥杆组件

URL参数更改时的侦听器事件

Android数据绑定中的属性更改时如何获得通知?

当前用户属性更改时的Firebase侦听器

用户更改时未触发Firebase Auth侦听器

当列表中项目的属性更改时,ListCollectionView上的LiveFiltering不会重新评估筛选器

如何在Codename One中触发属性更改侦听器

回调中的组件属性更改时,绑定未更新

Aurelia对自己的属性进行更改不会调用更改的侦听器

当父属性更改时,为派生属性触发PropertyChanged

使用事件侦听器时如何访问父容器上的属性?

具有双向绑定的可观察字段用法(删除属性更改侦听器)

jQuery:输入属性更改的侦听器

父属性更改时,嵌套属性的WPF绑定更新通知

JavaFX HTMLEditor文本更改侦听器

如何处理Property <T>,更改侦听器和属性的初始化?

POJO属性更改侦听器-理想方式

Embers js中的更改侦听器上的组合框

动作属性上的按钮->添加更改侦听器

属性更改时更新Aurelia绑定

当绑定数据更改时,用户控件上的依赖项属性不会更新属性

如何通过其已更改的事件侦听器设置复选框的选中属性

在更改时附加数据属性侦听器

当其他子控制器更改该范围属性时,如何在另一个控制器中为父范围的范围属性调用监视侦听器

用于按钮禁用属性更改的 Angular 5 侦听器或指令

您好,我需要设置依赖属性更改侦听器

当集合中的属性更改时在转换器上触发“ConvertBack”?