Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make a property which listen to changes of custom objects in javafx?

Tags:

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?

like image 218
Nazarii Mediukh Avatar asked Jun 20 '17 13:06

Nazarii Mediukh


People also ask

What is binding property in JavaFX?

JavaFX properties are often used in conjunction with binding, a powerful mechanism for expressing direct relationships between variables. When objects participate in bindings, changes made to one object will automatically be reflected in another object. This can be useful in a variety of applications.

What is string property?

public abstract class StringProperty extends ReadOnlyStringProperty implements Property<String>, WritableStringValue. This class provides a full implementation of a Property wrapping a String value. The value of a StringProperty can be get and set with ObservableObjectValue. get() , StringExpression.

What is JavaFX beans property?

The package javafx. beans. property defines read-only properties and writable properties, plus a number of implementations.


1 Answers

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.

like image 84
yab Avatar answered Oct 11 '22 13:10

yab