在JavaFX 应用中对创建表格最重要的是TableView, TableColumn和TableCell这三个类。
你可以通过实现数据模型(data model) 和 实现 单元格工厂(cell factory) 来填充表格。
表格类提供了表格列嵌入式的排序能力和必要时调整列宽度的功能。
下面开始学习表格类的相关内容。
创建一个表格
例子1-1
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class TableViewSample extends Application {
private TableView table = new TableView();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(300);
stage.setHeight(500);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
table.setEditable(true);
//设置自动拉满 table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
TableColumn firstNameCol = new TableColumn("First Name");
TableColumn lastNameCol = new TableColumn("Last Name");
TableColumn emailCol = new TableColumn("Email");
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);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
}
此表格组件 通过实例化TableView类来创建。
在该例子中,表格组件被添加到VBox 的布局容器中,然而你也可以直接将其添加到应用场景中。
例子 12-1定义了3列将用来存放地址簿的信息:一个联系人的 姓和名以及电子邮箱地址。列通过TableColumn这个类创建。
TableView 的getColumns方法可以获取之前创建过的列。在你的应用中,你可以用此方法动态的添加和移除表格列。
编译并运行此程序将获取输入输出 ,结果如图所示:
你可以通过setVisible 方法来控制列是否显示。
如:如果你的应用逻辑需要隐藏电子邮件地址,可以这样做:emailCol.setVisible(false).
将这句代码添加到例子1-1中,效果如图:
如果你的数据需要更加复杂的呈现方式,你可以创建嵌套列。
假设地址簿中的联系方式有两个电子邮箱账户。你需要两列来分别呈现第一个和第二个电子邮箱地址。
像下面代码中展示的一样,创建两个子列,然后调用emailCol 的getColumns方法
TableColumn firstEmailCol = new TableColumn("Primary");
TableColumn secondEmailCol = new TableColumn("Secondary");
emailCol.getColumns().addAll(firstEmailCol, secondEmailCol);
在这段代码里面添加到例子1-1中然后编译并运行, 此表格将呈现下图中的样子.
尽管表格已经添加到应用中,但是因为表格中没有数据,标准的标题“表中无内容”(表格内容为空)将呈现在表格中。
如果不想显示上述标题,你可以使用setPlaceholder 方法类制定 一个 Node(节点)对象呈现在空表格中。
定义数据模型( Data Model)
当你要在JavaFx应用中创建一个表格,最好先创建一个类来定义数据模型和提供将来和表格交互的方法和属性。例子1-2中定义了Person类来定义数据和地址簿。
例字1-2 创建 Person 类
public class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty 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 String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
}
firstName, lastName, 和 email这些字符串属性用来提供特殊数据元素的引用。
另外,每个数据元素都提供了get和set方法。 这样如果调用 getFirstName方法经返回firstName属性的值,可以通过调用setFirstName方法来为这个属性赋值 。
在数据模型已经在Person 类中呈现以后。你可以创建ObservableList 数组随心所欲的定义数据行(data rows) 在你的表格中展示
下面的代码片段实现了这个任务:
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")
);
下一步就是将这些数据和表格的列之间建立联系。你可以像例子1-3中那样通过对每个数据元素的属性定义来实现。
例子1-3 为列创建数据属性
firstNameCol.setCellValueFactory(
new PropertyValueFactory<Person,String>("firstName")
);
lastNameCol.setCellValueFactory(
new PropertyValueFactory<Person,String>("lastName")
);
emailCol.setCellValueFactory(
new PropertyValueFactory<Person,String>("email")
);
setCellValueFactory 方法为每个列定制单元工厂。单元工程通过使用PropertyValueFactory类来实现, 表格列的firstName, lastName和email 属性来引用Person中相应的属性的 。
当数据模型已经定义完毕,数据已经添加并关联到对应的列,你还可以通过TableView 的setItems 方法来添加表格数据:table.setItems(data)
.
因为ObservableList 对象能够跟踪表格元素的任何变化,当其中的数据变化,TableView 的内容也自动更新。
例子1-4 创建一个表格并添加数据
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class TableViewSample 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) {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(450);
stage.setHeight(500);
final Label label = new Label("Address Book");