![](/img/trans.png)
[英]JavaFX/SceneBuilder StringProperty[value: ] text in cell
[英]how to change final value of StringProperty type in javaFX?
我试图学习Tableview并得到了一些例子。
我不知道StringProperty如何工作。
尽管Class Person的字段是最终实例,
setEmailButton可以更改其值。
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.collections.*;
import javafx.event.*;
import javafx.geometry.Insets;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class PropertyBasedTableView extends Application {
private TableView<Person> table = new TableView<Person>();
private final ObservableList<Person> data = FXCollections.observableArrayList();
private void initData() {
data.setAll(
new Person("Jacob", "Smith", "jacob.smith@example.com"),
new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
new Person("Ethan", "Williams", "ethan.williams@example.com")
);
}
public static void main(String[] args) { launch(args); }
@Override public void start(Stage stage) {
initData();
stage.setTitle("Table View Sample");
stage.setWidth(450);
stage.setHeight(500);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
TableColumn lastNameCol = new TableColumn("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));
TableColumn emailCol = new TableColumn("Email");
emailCol.setMinWidth(200);
emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email"));
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
table.setPrefHeight(300);
final Button setEmailButton = new Button("Set first email in table to wizard@frobozz.com");
setEmailButton.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent event) {
if (data.size() > 0) {
data.get(0).setEmail("wizard@frobozz.com");
}
}
});
final VBox vbox = new VBox(10);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(label, table, setEmailButton);
stage.setScene(new Scene(new Group(vbox)));
stage.show();
}
public static class Person {
private final StringProperty firstName;
private final StringProperty lastName;
private final StringProperty email;
private Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public String getFirstName() { return firstName.get(); }
public void setFirstName(String fName) { firstName.set(fName); }
public StringProperty firstNameProperty() { return firstName; }
public String getLastName() { return lastName.get(); }
public void setLastName(String lName) { lastName.set(lName); }
public StringProperty lastNameProperty() { return lastName; }
public String getEmail() { return email.get(); }
public void setEmail(String inMail) { email.set(inMail); }
public StringProperty emailProperty() { return email; } // if this method is commented out then the tableview will not refresh when the email is set.
}
}
然后我自己下结论:“尤里卡!最终StringProperty类型的值可以更改!”
所以我做了测试
package zzzzDelete;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.stage.Stage;
class A{
void someTest(){
B insB = new B("why");
System.out.println(insB.getString());
insB.setString("omg");
System.out.println(insB.getString());
}
class B{
private final StringProperty someString;
private B(String someString){
this.someString = new SimpleStringProperty(someString);
}
public String getString(){
return someString.get();
}
public void setString(String newString){
this.someString = new SimpleStringProperty(newString); // error
}
}
}
public class SomeTest {
public static void main(String[] args){
A a = new A();
a.someTest();
}
}
由于final关键字而发生错误。
我对第一个例子和第二个例子非常困惑。
初始化后,您不能更改不可变( final
)字段(在构造函数中发生)。 相反,只需通过setValue(String)
设置StringProperty
的值:
class B {
private final StringProperty someString;
private B(String someString){
this.someString = new SimpleStringProperty(someString);
}
public String getString(){
return someString.get();
}
public void setString(String newString){
this.someString.setValue(newString);
}
public StringProperty stringProperty() {
return this.someString;
}
}
阅读JavaFX:属性和绑定教程 ,了解如何使用JavaFX属性。
下图应阐明更改StringProperty
工作方式:
类型B
对象始终引用相同的StringProperty
对象,因为引用someString
是final
并且不能更改(请参见红色箭头)。 但是someString
引用的SimpleStringProperty
对象是可变的 。 它包含一个名为value
的String
引用(请参见绿色箭头),可以将其更改为指向另一个String
对象,例如,通过调用setValue("second")
(请参见绿色的虚线箭头)。
将变量标记为final
,只能为其分配一个值。 在第二个示例中,由于尝试在setString(...)
方法中为someString
分配值,因此会出现编译错误:
this.someString = new SimpleStringProperty(newString);
不允许这样做,因为setString(...)
方法可以在同一对象上多次调用。
相比之下,在您的第一个示例中,只有final
变量(实例字段)才被赋值,这是在构造函数中进行的,当然,对于任何给定的对象只能调用一次。
注意, 给引用赋值是有区别的:
this.someString = new SimpleStringProperty(...);
并更改参考指向的对象的状态 :
this.firstName.set(fName);
即使firstName
是final
,第二个也很好。
如果您在第二个示例中编写类B
以遵循与第一个示例中的Person
类相同的模式,则它将正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.