SimpleStringProperty和SimpleIntegerProperty TableView JavaFX

所以我正在尝试学习如何使用JavaFx Tableview,并在本教程中简化:

Oracle tableview教程

在本教程中,他们表明,为了填充tableView,你必须用字符串填充它,但不只是你需要格式化任何字符串StringSimpleStringProperty

我尝试没有格式,结果是没有任何信息显示!

另外我发现如果你想在表中添加一个Integer ,你必须将它声明为SimpleIntegerProperty

现在我对JavaFx还不熟悉,但这是否意味着当我创建一个对象时,我必须格式化所有的整数和字符串以便能够填充我的TableView? 它似乎相当愚蠢,但也许有更高的目的? 还是有办法避免它?

尽管在某些情况下需要使用Properties,但您不需要在表数据对象中使用Properties来显示它们。

以下代码将显示基于Person类的人员表,该Person类仅包含String字段。

 import javafx.application.Application; import javafx.collections.*; 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 ReadOnlyTableView extends Application { private TableView table = new TableView(); private final ObservableList data = FXCollections.observableArrayList( new Person("Jacob", "Smith", "jacob.smith@example.com"), new Person("Isabella", "Johnson", "isabella.johnson@example.com"), new Person("Ethan", "Williams", "ethan.williams@example.com"), new Person("Emma", "Jones", "emma.jones@example.com"), new Person("Michael", "Brown", "michael.brown@example.com") ); public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { 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("firstName")); TableColumn lastNameCol = new TableColumn("Last Name"); lastNameCol.setMinWidth(100); lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName")); TableColumn emailCol = new TableColumn("Email"); emailCol.setMinWidth(200); emailCol.setCellValueFactory(new PropertyValueFactory("email")); table.setItems(data); table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); final VBox vbox = new VBox(); vbox.setSpacing(5); vbox.setPadding(new Insets(10, 0, 0, 10)); vbox.getChildren().addAll(label, table); stage.setScene(new Scene(new Group(vbox))); stage.show(); } public static class Person { private String firstName; private String lastName; private String email; private Person(String fName, String lName, String email) { this.firstName = fName; this.lastName = lName; this.email = email; } public String getFirstName() { return firstName; } public void setFirstName(String fName) { firstName = fName; } public String getLastName() { return lastName; } public void setLastName(String lName) { lastName = lName; } public String getEmail() { return email; } public void setEmail(String inMail) { email = inMail; } } } 

说明

使用Properties和ObservableLists的目的是这些是可听元素。 使用属性时,如果datamodel中属性属性的值发生更改,则TableView中项的视图将自动更新以匹配更新的datamodel值。 例如,如果某人的电子邮件属性的值设置为新值,则该更新将反映在TableView中,因为它会侦听属性更改。 相反,如果使用普通的String来表示电子邮件,则TableView不会刷新,因为它不会意识到电子邮件值的更改。

PropertyValueFactory文档详细描述了此过程:

如何使用此类的示例是:

 TableColumn firstNameCol = new TableColumn("First Name"); firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName")); 

在此示例中,“firstName”字符串用作Person类类型中假定的firstNameProperty()方法的引用(这是TableView项列表的类类型)。 此外,此方法必须返回Property实例。 如果找到满足这些要求的方法,则使用此ObservableValue填充TableCell。 此外,TableView将自动向返回的值添加一个观察者,以便TableView可以观察到触发的任何更改,从而导致单元格立即更新。

如果不存在与此模式匹配的方法,则会尝试调用get()或is()(即上例中的getFirstName()或isFirstName())。 如果存在与此模式匹配的方法,则此方法返回的值将包装在ReadOnlyObjectWrapper中并返回到TableCell。 但是,在这种情况下,这意味着TableCell将无法观察ObservableValue的更改(如上面第一种方法中的情况)。

更新

下面是第一个示例的对比示例,该示例演示了TableView如何根据对项的ObservableList的更改以及对基于属性的项属性的值的更改来观察和自动刷新。

 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 table = new TableView(); private final ObservableList 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"), new Person("Emma", "Jones", "emma.jones@example.com"), new Person("Michael", "Brown", "michael.brown@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("firstName")); TableColumn lastNameCol = new TableColumn("Last Name"); lastNameCol.setMinWidth(100); lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName")); TableColumn emailCol = new TableColumn("Email"); emailCol.setMinWidth(200); emailCol.setCellValueFactory(new PropertyValueFactory("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() { @Override public void handle(ActionEvent event) { if (data.size() > 0) { data.get(0).setEmail("wizard@frobozz.com"); } } }); final Button removeRowButton = new Button("Remove first row from the table"); removeRowButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { if (data.size() > 0) { data.remove(0); } } }); final Button resetButton = new Button("Reset table data"); resetButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { initData(); } }); final VBox vbox = new VBox(10); vbox.setPadding(new Insets(10, 0, 0, 10)); vbox.getChildren().addAll(label, table, setEmailButton, removeRowButton, resetButton); 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. } }