简体   繁体   中英

JavaFX binding: does BeanPathAdapter work?

I use for DTO POJOS. And for desktop client GUI I use JavaFX. And of course, I would like to have bidirectional (not mono!) data binding. I've found two solutions:

1) to use special classes Adapters. For example if we have POJO class Person, then we create JavaFx (*property) class PersonAdapter. Besides in POJO Person we add PropertyChangeSupport. This method works, however it's necessary for every DTO write DTOAdapter. - bad.

2)I've found this article https://ugate.wordpress.com/2012/06/14/javafx-programmatic-pojo-bindings/ and this code for javafx8 https://github.com/JFXtras/jfxtras-labs/blob/8.0/src/main/java/jfxtras/labs/scene/control/BeanPathAdapter.java . To tell the truth I didn't understand how they will find out if the POJO is changed. By other words if javafx changes - POJO changes it's clear. But if POJO changes? Some mystery I thought and desided to test

class Person{
 private String name;
 public void setName(String name){
 this.name=name;
 }
 public String getName(){
  return this.name;
  }
}

And the testing code:

Person person=new Person();
SimpleStringProperty sp=new SimpleStringProperty();
BeanPathAdapter<Person> testPA = new BeanPathAdapter<>(person);
testPA.bindBidirectional("name", sp);
person.setName("Name1");
System.out.println("Test1:"+sp.get());
sp.set("Name2");
System.out.println("Test2:"+test.getName()

Here is the result:

Test1:null
Test2:Name2

So we see that direction javafx property -> pojo works. However, pojo->javafx property doesn't. Or I do something wrong, or it doesn't work? Maybe someone will sugest a better solution?

Unfortunately, it doest't work that. bindBidirectional doesn't modify bean for listening it changes. You can be confused with name bindBidirectional. That can be explained as it binds bidirectionally property (sp in your example) and BeanPathAdapter inner property. javafx -> adapter (and also wrapped bean) and adapter -> javafx in your terms.

So, changes of bean doesn't effects adapter and binded properties. But how we can change adapter without changing property and bean? By changing another property binded to same bean property. For example:

    Person person = new Person();

    SimpleStringProperty firstProperty = new SimpleStringProperty();
    SimpleStringProperty secondProperty = new SimpleStringProperty();

    BeanPathAdapter<Person> testPA = new BeanPathAdapter<>(person);

    testPA.bindBidirectional("name", firstProperty);
    testPA.bindBidirectional("name", secondProperty);

    firstProperty.set("fromFirst");
    System.out.println("first:" + firstProperty.get() + " second=" + secondProperty.get() + " bean=" + person.getName());
    secondProperty.set("fromSecond");
    System.out.println("first:" + firstProperty.get() + " second=" + secondProperty.get() + " bean=" + person.getName());

    person.setName("fromBean");
    System.out.println("first:" + firstProperty.get() + " second=" + secondProperty.get() + " bean=" + person.getName());

Here is the result:

    first:fromFirst second=fromFirst bean=fromFirst
    first:fromSecond second=fromSecond bean=fromSecond
    first:fromSecond second=fromSecond bean=fromBean

But you can force update properties by adding testPA.setBean(person); after each changes of bean which you want to handle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM