Issue
I have two string
private StringProperties firstName;
private StringProperties lastName;
private StringProperties nickName;
the first and last name are picked by user, the nickName is a concatenation of first 3 character of first and lastname
How i can do that?
Actually i initialize it like that (this is the entire class).
public class Person {
private StringProperty firstName;
private StringProperty lastName;
private StringProperty nickName;
private ObservableList<Evento> eventi = FXCollections.observableArrayList();
public Person(String firstName, String lastName) {
this.firstName = new SimpleStringProperty(firstName);
this.lastName = new SimpleStringProperty(lastName);
if (firstName.length() > 2 && lastName.length() > 2)
this.nickName = new SimpleStringProperty(firstName.trim().substring(0,3).concat(lastName.trim().substring(0,3)));
else
this.nickName = new SimpleStringProperty("");
}
public ObservableList<Evento> getEventi() {
return eventi;
}
public String getFirstName() {
if(firstName == null) firstName = new SimpleStringProperty(this,"firstName");
return firstName.get();
}
public StringProperty firstNameProperty() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public String getLastName() {
if(lastName == null) lastName = new SimpleStringProperty(this, "lastName");
return lastName.get();
}
public StringProperty lastNameProperty() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public String getNickName() {
if(nickName == null) nickName = new SimpleStringProperty(this,"nickName");
return nickName.get();
}
public StringProperty nickNameProperty() {
return nickName;
}
@Override
public String toString() {
return getNickName() + "(" + getLastName() + " " + getFirstName() + ")";
}
}
but when i let the user change first or lastName, the nickName won't update.
Solution
You should use ReadOnlyStringProperty
for the nickname:
private ReadOnlyStringWrapper nickName= new ReadOnlyStringWrapper();
...
public final String getNickName() {
return nickName.get();
}
public final ReadOnlyStringProperty nickNameProperty() {
return nickName.getReadOnlyProperty();
}
As for binding, you can use utility methods from Bindings
class or implement your own binding for any other complicated cases. This example uses createStringBinding()
method. It takes Callable
functional interface, which will be used to calculate new value, and list of observable properties, which values will be observed for changes:
public Person(String firstName, String lastName) {
this.firstName = new SimpleStringProperty(firstName);
this.lastName = new SimpleStringProperty(lastName);
this.nickName.bind(Bindings.createStringBinding(()->{
if(this.firstName.get().length() > 2 && this.lastName.get().length() > 2) {
return this.firstName.get().substring(0,3).concat(this.lastName.get().trim().substring(0,3));
} else {
return "";
}
}, this.firstName, this.lastName));
}
Answered By - whitesite