在本章中,你将会创建一个地址簿应用程序,其中包括一个带有姓名和邮件地址的表格。本教程展示了如何操作带有数据的表格,包括数据排序,单元格中的数据对齐,向表格内增加行。
在开始之前,我们假定你对FXML相关的一些知识有了相当的了解,至少你已经完成了官方文档中的“开始JavaFX之旅”(“Getting Started”)系列课程,尤其对于下列知识点你必需已经掌握:
在你开始这个教程之前,确保IDE版本支持对应版本的JavaFX(译者注:包括要支持Java8)
在IDE中创建工程,在其中创建FXMLTableView.java、FXMLTableViewController.java、fxml_tableview.fxml三个文件。注意如果是使用NetBeansIDE来创建的,则需要创建FXMLTableView工程,并重命名其中对应的文件。现在FXMLTableView类的代码如下:
public class FXMLTableView extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("FXML TableView Example");
Pane myPane = (Pane)FXMLLoader.load(getClass().getResource
("fxml_tableview.fxml"));
Scene myScene = new Scene(myPane);
primaryStage.setScene(myScene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
注意目前Java类中并没有包括创建场景的相关代码。在教程的下一部分会告诉你如何在FXML文件中来创建场景。
现在开始创建用户界面,先创建一个GridPane布局容器作为场景的根节点。然后增加一个Label和TableView控件作为其子节点。
1. 将fxml_tableview.fxml文件内容改为下面的内容:
3. 增加Inset类的import语句
运行程序,你将会看到看到一个带有文本“Address Book”的Label以及一个带有文本“No columns in table”的表格,如下图:
使用TableColumn类来在表格中增加3列,分别用于显示数据:First Name,Last Name以及Email Address。代码如下:
参考API文档可获取更多信息。
下图展现了运行效果:
package fxmltableview;
import javafx.beans.property.SimpleStringProperty;
public class Person {
private final SimpleStringProperty firstName = new SimpleStringProperty("");
private final SimpleStringProperty lastName = new SimpleStringProperty("");
private final SimpleStringProperty email = new SimpleStringProperty("");
public Person() {
this("", "", "");
}
public Person(String firstName, String lastName, String email) {
setFirstName(firstName);
setLastName(lastName);
setEmail(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);
}
}
下面定义每一行的数据,并将其关联到表格。
1. 在fxm_tableview.fxml文件中,创建一个ObservableList列表并定义一些希望展现在表格中的数据,在和 标签之间添加代码,样例代码如下:
3. 引入需要的包
(译者注:第三行注意需要根据实际情况调整,因为有可能你创建的项目的包名不是fxmltableview)
下图展现了此时程序的运行情况:
此时你可以尝试TableView类的一些内置的功能特点:
在本节中将进行排序顺序的设置,使得First Name列在应用启动时按字母升序排列。首先需要为对应的列创建一个ID,然后创建一个reference来应用它。
1.为First Name 列增加ID:
2.指定排序顺序,在和两个标记之间增加代码:
运行后界面如下:
prefWidth="100">
prefWidth="100">
prefWidth="200">
运行效果如下图所示,列宽被扩大后所有数据得以全部显示。
单元格中的数据对齐方式是可以定制的。你需要创建一个名为FormattedTableCellFactory的类来实现对应的逻辑,然后在FXML的
1. 在IDE中创建新类FormattedTableCellFactoryand
2.修改FormattedTableCellFactoryand类的代码,使其实现Callback接口,并在其中创建TextAlignment和Formt类实例。在下面的代码中,参数S是TableView泛型的类型、参数T是单元格的内容的类型:public class FormattedTableCellFactory
implements Callback, TableCell> {
private TextAlignment alignment;
private Format format;
public TextAlignment getAlignment() {
return alignment;
}
public void setAlignment(TextAlignment alignment) {
this.alignment = alignment;
}
public Format getFormat() {
return format;
}
public void setFormat(Format format) {
this.format = format;
}
3.实现TabCell和TableColumn接口,将下列代码添加到类中。这段代码实现了TableCell接口的updateItem方法,并在其中调用了单元格setTextAlign方法。
@Override
@SuppressWarnings("unchecked")
public TableCell call(TableColumn p) {
TableCell cell = new TableCell() {
@Override
public void updateItem(Object item, boolean empty) {
if (item == getItem()) {
return;
}
super.updateItem((T) item, empty);
if (item == null) {
super.setText(null);
super.setGraphic(null);
} else if (format != null) {
super.setText(format.format(item));
} else if (item instanceof Node) {
super.setText(null);
super.setGraphic((Node) item);
} else {
super.setText(item.toString());
super.setGraphic(null);
}
}
};
cell.setTextAlignment(alignment);
switch (alignment) {
case CENTER:
cell.setAlignment(Pos.CENTER);
break;
case RIGHT:
cell.setAlignment(Pos.CENTER_RIGHT);
break;
default:
cell.setAlignment(Pos.CENTER_LEFT);
break;
}
return cell;
}
}
4.增加必需的import语句。
5.在fxml_tableview.fxml中的
你可以在其它的列中通过left、right或者center来指定不同的对齐方式。
运行结果如下:
通过在FXMLTableViewControllerclass类中增加代码逻辑,可以使得用户可以向表格中增加数据。
1.打开FXMLTableViewController.java文件
2.按照下面的代码修改FXMLTableViewController类:
public class FXMLTableViewController {
@FXML private TableView tableView;
@FXML private TextField firstNameField;
@FXML private TextField lastNameField;
@FXML private TextField emailField;
@FXML
protected void addPerson(ActionEvent event) {
ObservableList data = tableView.getItems();
data.add(new Person(firstNameField.getText(),
lastNameField.getText(),
emailField.getText()
));
firstNameField.setText("");
lastNameField.setText("");
emailField.setText("");
}
}
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
4. 在fxml_tableview.fxml文件中,在 前增加下面的代码:
GridPane.rowIndex="2">
prefWidth="90"/>
prefWidth="90"/>
prefWidth="150"/>
运行后界面如下:
后续可以尝试一下这些内容:
1. 提供一个filter来校验输入的数据格式的正确性。
2. 使用CSS来自定义表格外观,区分区空行和非空行。可参考官方文档中的“Styling UIControls with CSS”。
3. 允许在表格中编辑数据。可参考官方文档中的“Editing Data in the Table”
看一看Introduction to FXML document,其中提供了更多关于FXML的信息。这篇文当在API文档的javafx.fxml包中。