5

Let's assume I have an entity class Foo which contains some fields, getters, setters and constructor. For example:

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;
}
}

Then i want to know when a or b changes. I know that there is an ObjectProperty in javaFX. So i'm creating Object Property:

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

Then in order to know about changes of a and b fields, I add ChangeListener:

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

Then experiments:

fooProperty.set(new Foo());

working well, but next line:

fooProperty.get().setA(10)

does not invoke listener. The reason for that is clear. Last line actually doesn't change the Foo object (reference remains the same).

I have some possible solutions. But all of them are not elegant enough. For example changing each field as a property and adding the same listener for each variable.

So, the question is. What is the way to add listener for changes of the fields of custom object?

  • Isn't this just solved by implementing `a` and `b` as `IntegerProperty`s and using a fixed `Foo` instance? Or am I misunderstanding the question? – James_D Jun 20 '17 at 15:24

1 Answers1

4

do not know if this what you want or not, you may take it for reference.

First i create a class, its function is to carry information.

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;
  }
}

then, create the Foo class, it has two Object fields, we are going to listen if they change.

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;
  }
}

in other class, using the code below, to listen if the a or b in foo has change.

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());

in this case, we just use Object class, if you wanna use a custom class to replace, don't forget to override its hashCode() and equals() methods to determine whether the two objects are the same.

yab
  • 227
  • 1
  • 12