To Put or not to put JavaFX Properties into Entities?
Just some ideas that I found and will test some day
- JavaFX Property into Entity with “super lazy” behavior
- JavaFX Property into Entity with Property Change Listener
- JavaFX Property into Entity with Simple*Property
- JavaFX Property outside Entity
- JavaFX Property unidirectional outside Entity
- JavaFX Property bidirectional binding outside Entity
- Adapter pattern
- JavaFX property outside Entity. Using PropertyValueFactory
Approach 1
JavaFX Property into Entity with “super lazy” behavior
// FROM: https://stackoverflow.com/questions/32973827/javafx-property-based-entity-vs-property-based-wrapper
@Entity
@Access(AccessType.PROPERTY)
public class Person {
private IntegerProperty age ;
private int _age ;
private StringProperty name ;
private String _name ;
private int id ;
@Id
public int getId() {
return id ;
}
public void setId(int id) {
this.id = id ;
}
public IntegerProperty ageProperty() {
if (age == null) {
age = new SimpleIntegerProperty(_age);
}
return age ;
}
public int getAge() {
if (age == null) {
return _age ;
} else {
return age.get();
}
}
public void setAge(int age) {
if (this.age == null) {
_age = age ;
} else {
this.age.set(age);
}
}
public StringProperty nameProperty() {
if (name == null) {
name = new SimpleStringProperty(_name);
}
return name ;
}
public String getName() {
if (name == null) {
return _name ;
} else {
return name.get();
}
}
public void setName(String name) {
if (this.name == null) {
_name = name ;
} else {
this.name.set(name);
}
}
}
Approach 2
JavaFX Property into Entity with Property Change Listener
// FROM: https://stackoverflow.com/questions/32973827/javafx-property-based-entity-vs-property-based-wrapper
@Entity
public class Person {
@Id
private int id ;
private int age ;
private String name ;
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public int getAge() {
return age ;
}
public void setAge(int age) {
int oldAge = age ;
this.age = age ;
pcs.firePropertyChange("age", oldAge, age);
}
public String getName() {
return name ;
}
public void setName(String name) {
String oldName = name ;
this.name = name ;
pcs.firePropertyChange("name", oldName, name);
}
// ...
}
Approach 3
JavaFX Property into Entity with Simple*Property
// FROM: https://stackoverflow.com/questions/23522130/javabean-wrapping-with-javafx-properties
@Entity
@Access(AccessType.PROPERTY)
public class Person {
private final StringProperty firstName = new SimpleStringProperty(this, "firstName");
public final String getFirstName() {
return firstName.get();
}
public final void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public StringProperty firstNameProperty() {
return firstName ;
}
// ... other properties, etc
}
Approach #4
JavaFX Property outside Entity
public class PersonProperties {
private final Person person;
public PersonProperties(Person person) {
this.person = person;
}
private final StringProperty name = new SimpleStringProperty() {
@Override
public void set(String string) {
super.set(string);
person.setName(string);
}
}
public final String getName() {
return name.get();
}
public final void setName(String value) {
name.set(value);
}
}
Approach 5
JavaFX Property unidirectional outside Entity. Property generated by Property Adapter factory and Simple entity (without property change listeners)
PS: property unidirectional (change the value in the table, the entity will be updated BUT change value in entity will not update the value displayed)
// FROM: https://stackoverflow.com/questions/31941805/put-together-javafx-properties-and-jpa-entities-no-mixed-mode
@Entity
public class Person {
private String firstName ;
private String lastName ;
@Id
private Integer id ;
public String getFirstName() {
return firstName ;
}
public void setFirstName(String firstName) {
this.firstName = firstName ;
}
public String getLastName() {
return lastName ;
}
public void setLastName(String lastName) {
this.lastName = lastName ;
}
}
TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setCellValueFactory(cellData -> {
try {
return JavaBeanStringPropertyBuilder.create()
.bean(cellData.getValue())
.name("firstName")
.build();
} catch (NoSuchMethodException exc) {
throw new RuntimeException(exc);
}
});
Approach 6
JavaFX Property bidirectional binding outside Entity
Property generated by Property Adapter factory and Entity with property change listeners
// FROM: https://stackoverflow.com/questions/31941805/put-together-javafx-properties-and-jpa-entities-no-mixed-mode
@Entity
public class Person {
private String firstName ;
private String lastName ;
private PropertyChangeSupport pcs ;
public Person() {
pcs = = new PropertyChangeSupport(this);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcs.removePropertyChangeListener(listener);
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
String oldName = this.firstName ;
this.firstName = firstName;
pcs.firePropertyChange("firstName", oldName, this.firstName);
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
String oldName = this.lastName ;
this.lastName = lastName;
pcs.firePropertyChange("lastName", oldName, this.lastName);
TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setCellValueFactory(cellData -> {
try {
return JavaBeanStringPropertyBuilder.create()
.bean(cellData.getValue())
.name("firstName")
.build();
} catch (NoSuchMethodException exc) {
throw new RuntimeException(exc);
}
});
Approach 7
Adapter pattern
// FROM https://stackoverflow.com/questions/31941805/put-together-javafx-properties-and-jpa-entities-no-mixed-mode
// normal entity with getters and setters
@Entity
public class EntityClass implements Serializable {
@Id
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
}
public interface IFXEntity {
void setYear(String year);
String getYear();
}
public class FXEntityClass implements IFXEntity {
private final StringProperty yearProperty = new SimpleStringProperty();
private StringProperty getYearProperty() {
return yearProperty;
}
public setYear(String year) {
this.yearProperty.set(year);
}
public String getYear() {
this.yearProperty.get();
}
}
public class EntityClassToFXEntityClassAdaptor implements IFXEntityClass{
private EntityClass entity;
private final StringProperty yearProperty=new SimpleStringProperty();
public EntityClassToFXEntityClassAdaptor(EntityClass e){
this.entity = e;
this.yearProperty.set(e.getYear());
}
public StringProperty getYearProperty(){
return this.yearProperty;
}
public void setYear(String year) {
this.year.set(year);
}
public String getYear() {
return this.year.get();
}
}
EntityClass ec=something; //get an instance of JPAEntity
EntityClassToFXEntityClassAdaptor adaptor=new EntityClassToFXEntityClassAdaptor(ec);
adaptor.getYearProperty();
Approach 8
JavaFX property outside Entity. Using PropertyValueFactory
import javafx.fxml.Initializable;
import javafx.scene.control.cell.PropertyValueFactory
public class PersonDataController implements Initializable;
@FXML private TabelColumn<Person, String> colFirstName;
@FXML private TabelColumn<Person, String> colLastName;
@Override
public void initialize(URL localtion, ResourceBundle resources) {
colFirstName.setCellValueFactory(new PropertyValueFactory<Person,String>("FirstName"));
colLastName.setCellValueFactory(new PropertyValueFactory<Person,String>("LastName"));
}
???
// FROM: https://stackoverflow.com/questions/23522130/javabean-wrapping-with-javafx-properties
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
public class Bean {
private String name ;
private final PropertyChangeSupport propertySupport ;
public Bean(String name) {
this.name = name ;
this.propertySupport = new PropertyChangeSupport(this);
}
public Bean() {
this("");
}
public String getName() {
return name ;
}
public String setName(String name) {
String oldName = this.name ;
this.name = name ;
propertySupport.firePropertyChange("name", oldName, name);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertySupport.addPropertyChangeListener(listener);
}
}
????
StringProperty nameProperty = new JavaBeanStringPropertyBuilder().bean(??).name("name").build();
Bean bean = new Bean();
StringProperty nameProperty() = new JavaBeanStringPropertyBuilder()
.bean(bean)
.name("name")
.build();
nameProperty().addListener((obs, oldName, newName) -> System.out.println("name changed from "+oldName+" to "+newName));
bean.setName("James");
System.out.println(nameProperty().get());