所以我试着学习如何使用JavaFx Tableview,我偶然发现了这个教程:
Oracle tableview tutorial
在本教程中,他们展示了为了填充tableView,您必须用String填充它,而不是只填充任何必须将String
格式化为SimpleStringProperty
的字符串
我尝试不使用该格式,结果是没有显示任何信息!
此外,我还发现,如果要向表中添加Integer
,则必须将其声明为SimpleIntegerProperty
现在我对JavaFx还很陌生,但是这是否意味着当我创建一个对象时,我必须格式化我所有的整数和字符串才能填充我的TableView?这看起来很愚蠢,但也许有更高的目的?或者有没有办法避免它?
发布于 2012-11-15 02:48:11
您不需要在表数据对象中使用Properties来显示它们,尽管在某些情况下需要使用Properties。
下面的代码将显示一个基于Person类的people表,该类只有字符串字段。
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", "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<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中,因为它会侦听属性的更改。相反,如果使用普通字符串表示电子邮件,TableView将不会刷新,因为它不会知道电子邮件值的变化。
PropertyValueFactory文档详细介绍了此过程:
有关如何使用此类的示例如下:
TableColumn firstNameCol = new TableColumn("First Name");firstNameCol.setCellValueFactory(new PropertyValueFactory( "firstName“));在本例中,”firstName“字符串用作对Person类类型(即TableView项目列表的类类型)中假定的firstNameProperty()方法的引用。此外,此方法必须返回一个属性实例。如果找到满足这些要求的方法,则使用此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<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"),
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<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 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.
}
}
https://stackoverflow.com/questions/13381067
复制相似问题