When to use StringProperty over String?

2020-03-09 08:38发布

问题:

I am developing an application in JavaFX where I want to represent information of a Person in a single Person class. I came across a tutorial where a Person's name was being represented as a StringProperty instead of String. I have searched for the differences of these and found out this and this but the explanation there is not sufficient for me to grab the concept. Some post on the net said there are advantages of using StringProperty over String but could not mention them.

Now my question is: What conditions require one to use StringProperty over String and what are the advantages of doing that?

Why this:

StringProperty firstName;

Over this:

String firstName;

回答1:

When to use StringProperty firstName over String firstName?

Use it when this firstName variable is going to be observed by others. You also can observe it by attaching a listener. You can use this variable in bindings with other observable objects of JavaFX. In some circumstances it is mandatory to use JavaFX Property, like Person list rendered with tableView which is editable. To reflect the changes immediately in edited cell, the underlying bound field should be a property.



回答2:

JavaFX tries to enable the MVC-Pattern. The Model should be created with Properties to take advantage of Binding. In your case the Model is the Person class, so you can simply add the StringProperty firstName. But in JavaFX you have to take care of the other naming convention as for simple getter and setter in a Pojo Bean.

Naming Convention for Properties in JavaFX are:

 public class Person {
     private StringProperty firstName;
     public void setFirstName(String value) { firstNameProperty().set(value); }
     public String getFirstName() { return firstNameProperty().get(); }
     public StringProperty firstNameProperty() { 
         if (firstName == null) firstName = new SimpleStringProperty(this, "firstName");
         return firstName; 
     }

     private StringProperty lastName;
     public void setLastName(String value) { lastNameProperty().set(value); }
     public String getLastName() { return lastNameProperty().get(); }
     public StringProperty lastNameProperty() { 
         if (lastName == null) lastName = new SimpleStringProperty(this, "lastName");
         return lastName; 
     } 
 }

After that you be able to bind for example a TableColumn of a TableView to the Property "lastName"

TableView<Person> table = new TableView<Person>();

ObservableList<Person> teamMembers = getTeamMembers();
table.setItems(teamMembers);

TableColumn<Person,String> lastNameCol = new TableColumn<Person,String>("Last Name");
lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName"));

Without a Property this would be much more code and you won't have the advantages of implemented ChangeListener/InvalidationListener support.

The example above comes from JavaFX TableView

So the recommended way in making a Model for JavaFX is using JavaFX-Properties and not the build in types.