简体   繁体   中英

How i can bind two substring to one?

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.

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

}

You can use Bindings.format :

nickName.bind(Bindings.format("%.3s%.3s", firstName, lastName));

The 3 in %.3s is the maximum length of the string.


This won't do any trimming of the strings though, (you could do that before passing the strings to firstName and lastName ).

It will also work on strings that are smaller than 3 characters. So, you can get nicknames like FoBar , FooB or Bar (if the first name is an empty string).

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