是否有可能创建一个属性来监听javafx中自定义对象的更改?

时间:2017-06-20 13:25:40

标签: javafx properties binding object-property

假设我有一个实体类Foo,它包含一些字段,getter,setter和构造函数。例如:

public class Foo {
private Integer a = 0;
private Integer b = 0;

public Foo() {
}

public Integer getA() {
    return a;
}

public void setA(Integer a) {
    this.a = a;
}

public Integer getB() {
    return b;
}

public void setB(Integer b) {
    this.b = b;
}
}

然后我想知道a或b何时发生变化。我知道javaFX中有一个ObjectProperty。所以我正在创建对象属性:

ObjectProperty<Foo> fooProperty = new SimpleObjectProperty<>(new Foo());

然后,为了了解a和b字段的变化,我添加了ChangeListener:

fooProperty.addListener((observable, oldValue, newValue) -> {
    System.out.println("Property changed!");
});

然后实验:

fooProperty.set(new Foo());

运作良好,但下一行:

fooProperty.get().setA(10)

不会调用侦听器。原因很清楚。最后一行实际上并没有改变Foo对象(引用保持不变)。

我有一些可能的解决方案。但所有这些都不够优雅。例如,将每个字段更改为属性,并为每个变量添加相同的侦听器。

所以,问题是。为自定义对象的字段更改添加侦听器的方法是什么?

1 个答案:

答案 0 :(得分:1)

不知道这是否是你想要的,你可以把它作为参考。

首先我创建一个类,它的功能是携带信息。

public class EventObj{
  private String message;
  private Object newObj;

  public EventObj(String msg, Object obj){
    this.message = msg;
    this.newObj = obj;
  }

  public String getMessage(){
    return this.message;
  }

  public Object getNewObj(){
    return this.newObj;
  }
}

然后,创建Foo类,它有两个Object字段,如果它们发生变化我们会听。

public class Foo{
  private SimpleObjectProperty<Object> a;
  private SimpleObjectProperty<Object> b;

  private SimpleObjectProperty<EventObj> out;


  public Foo(){
    a = new SimpleObjectProperty<>();
    b = new SimpleObjectProperty<>();
    out = new SimpleObjectProperty<>();
    initEvent();
  }

  private void initEvent(){
    a.addListener(new ChangeListener<Object>(){
      @Override
      public void changed(ObservableValue<? extends Object> observable, Object oldValue, Object newValue){
        out.set(new EventObj("a changed", newValue));
      }
    });

    b.addListener(new ChangeListener<Object>(){
      @Override
      public void changed(ObservableValue<? extends Object> observable, Object oldValue, Object newValue){
        out.set(new EventObj("b changed", newValue));
      }
    });
  }

  public void setA(Object a){
    this.a.set(a);
  }

  public void setB(Object b){
    this.b.set(b);
  }

  public SimpleObjectProperty<EventObj> outProperty(){
    return out;
  }
}

在其他类中,使用下面的代码来监听foo中的a或b是否有变化。

Foo foo = new Foo();
foo.outProperty().addListener(new ChangeListener<EventObj>(){
  @Override
  public void changed(ObservableValue<? extends EventObj> observable, EventObj oldValue, EventObj newValue){
    System.out.println(newValue.getMessage() + ", new value is : " + newValue.getNewObj());
  }
});

foo.setA(new Object());
foo.setB(new Object());

在这种情况下,我们只使用Object类,如果您想使用自定义类进行替换,请不要忘记覆盖其hashCode()和equals()方法以确定这两个对象是否相同。