【问题标题】:JavaFX Property's invalidate() method not called with bindingJavaFX 属性的 invalidate() 方法未通过绑定调用
【发布时间】:2017-02-06 21:50:24
【问题描述】:

我正在尝试使用一些绑定功能在 JavaFX 中制作自定义控件。这是我的问题:我有一个带有DoubleProperty 的类,我用它来计算自定义控件中元素的位置。代码如下:

public class CustomControl extends Region {
  private DoubleProperty positionProperty;

  public CustomControl() {
    positionProperty= new DoublePropertyBase(0.0) {
      @Override public Object getBean() { return CustomControl.this; }
      @Override public String getName() { return "position"; }
      @Override protected void invalidated() { updatePostion(); }
    };
  }

  public DoubleProperty positionProperty() { return positionProperty; }
  public double getPosition() { return positionProperty.get(); }
  public void setPosition(double value) { positionProperty.set(value); }

  private void updatePosition() {
    double value = doubleProperty.get();
    //compute the new position using value
  }
}

在我的应用程序中,我有两个CustomControls,我希望当我在第一个上调用setPosition() 方法时,第二个也更新其组件的位置。为此,我绑定了两个CustomControls 中的positionProperty,如下所示:

CustomControl control1 = new CustomControl();
CustomControl control2 = new CustomControl();
control2.positionProperty.bind(control1.positionProperty);

然后当我打电话给例如

control1.setPosition(50.0);

只有control1的组件的位置被更新,确实当我调用方法setPosition()时,实际上调用了control1positionProperty的方法invalidated(),而不是其中的一个positionPropertycontol2 正如我所料。我应该如何实现我想要的?谢谢!

PS:我还注意到使用方法 bindBidirectional() 而不是 bind() 有效,但它不应该只使用 bind() 吗?

编辑:此处提供示例代码:https://luca_bertolini@bitbucket.org/luca_bertolini/customcontrolexample.git

【问题讨论】:

  • 您创建DoubleProperty 的匿名类实现的任何原因?您的问题可能源于您重写了 invalidated 方法,而没有调用基本 (super) 方法。
  • @sillyfly 我创建了一个匿名类,因为我需要在屏幕上显示大量这些CustomControls,并且使用匿名类而不是在属性上设置侦听器将提供更少的内存使用并且计算复杂度更低。 invalidate() 的默认实现也是空的,所以无论我是否调用super.invalidate(),它都不会发生太大变化。
  • 发布minimal reproducible example。我对此进行了测试,结果完全符合预期(System.out.println(control2.getPosition()); 显示为50.0)。您尚未发布的代码中的其他地方一定有错误。
  • 我添加了一个重现问题的示例项目...我做错了还是实现我想要的唯一方法是在属性上使用侦听器?

标签: javafx properties binding custom-controls invalidation


【解决方案1】:

JavaFX 对所有绑定使用惰性求值,这意味着当您的 out.positionProperty 对象发生更改时,不会立即考虑新值。当且仅当随后请求该值时才会发生这种情况。

试试这个:

out.positionProperty().addListener(new InvalidationListener() {
    @Override
    public void invalidated(final Observable observable) {
       // System.out.println("It must go now.");
    }
});

您会发现这一次您的代码可以按您的意愿运行。

【讨论】:

  • 是的,它有效。我想这是实现我想要的唯一方法。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-30
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多