雖然在某些情況下需要使用屬性,但您不需要在表數據對象中使用Properties來顯示屬性。
下面的代碼將顯示基於僅具有字符串字段的Person類的人員表。
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<Person> table = new TableView<Person>();
private final ObservableList<Person> data =
FXCollections.observableArrayList(
new Person("Jacob", "Smith", "[email protected]"),
new Person("Isabella", "Johnson", "[email protected]"),
new Person("Ethan", "Williams", "[email protected]"),
new Person("Emma", "Jones", "[email protected]"),
new Person("Michael", "Brown", "[email protected]")
);
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<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);
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; }
}
}
說明
使用性能及ObservableLists的目的是,這些是可聽元素。使用屬性時,如果數據模型中屬性屬性的值發生更改,則TableView中的項目視圖會自動更新以匹配更新的數據模型值。例如,如果某個人的電子郵件屬性的值設置爲新值,則該更新將反映在TableView中,因爲它會偵聽屬性更改。相反,如果使用純String代表電子郵件,則TableView將不會刷新,因爲它不會意識到電子郵件值更改。
的PropertyValueFactory文檔詳細描述了這一過程:
的如何使用這個類的一個例子是:
TableColumn<Person,String> firstNameCol = new TableColumn<Person,String>("First Name");
firstNameCol.setCellValueFactory(new PropertyValueFactory<Person,String>("firstName"));
在這個例子中,「名字」的字符串被用作參考以 假設Person類類型(即 TableView項列表的類類型)中的firstNameProperty()方法。此外,此方法 必須返回一個Property實例。如果找到符合這些 要求的方法,則TableCell將填充此ObservableValue。此外,TableView會自動將 觀察者添加到返回值中,以便TableView觀察到的任何更改觸發爲 ,從而導致單元立即更新。
如果沒有方法匹配該模式的存在,對於試圖呼叫得到()是()(即 是,的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<Person> table = new TableView<Person>();
private final ObservableList<Person> data = FXCollections.observableArrayList();
private void initData() {
data.setAll(
new Person("Jacob", "Smith", "[email protected]"),
new Person("Isabella", "Johnson", "[email protected]"),
new Person("Ethan", "Williams", "[email protected]"),
new Person("Emma", "Jones", "[email protected]"),
new Person("Michael", "Brown", "[email protected]")
);
}
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 [email protected]");
setEmailButton.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent event) {
if (data.size() > 0) {
data.get(0).setEmail("[email protected]");
}
}
});
final Button removeRowButton = new Button("Remove first row from the table");
removeRowButton.setOnAction(new EventHandler<ActionEvent>() {
@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<ActionEvent>() {
@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.
}
}
這是一個寫得不好的教程。他們掩蓋了太多重要的觀點,例如泛型。 –