表格对于应用程序中的数据输入和显示具有重要意义。表视图支持表格式的显示。这种格式使得纠正和检查数据模式更加容易。
由于这种数据显示格式是在像Microsoft Excel这样的表格应用程序中创建的,所以开发人员在事务处理系统(TPS)和管理信息系统(MIS)中更喜欢它。
随着对用户界面的关注,JavaFX以表格的形式表示数据。然而,人们只能查看,而不能单独编辑每个单元。
本文将在解决这个问题时提供解决方案。在本文结束时,读者将学会创建一个可编辑的表格视图,从而能够更容易地直接在表格上更新数据。
主要收获
在文章结束时,读者将能够完成以下工作。
- 创建一个[TableView]。
- 格式化表格。
- 在
TableView上添加数据项。 - 通过使用其控制器使
TableView可编辑。 - 获取已编辑的项目。
前提条件
本文是一篇关于JavaFX的中级文章。
为了方便跟进文章的内容,以下是需要的技能和工具。
- 一个好的Java IDE。建议使用最新的IntelliJ版本。
- 一个良好的互联网连接。
- 机器上安装的Java SDK。我们将使用JDK 17。
注意:系统要求和规格可能会随着时间而改变。请务必注意新的要求以及如何在项目中实现它们。
文章结构
在文章中,将按照以下步骤来完成关键收获部分中指出的要点。
- 项目初始化。
- 表的创建和设计。
- 向表添加虚拟数据。
- 使表的数据可编辑。
- 取出已编辑的内容。
让我们从第一步开始。
项目初始化
要建立一个新的JavaFX项目,请执行以下步骤。
- 打开IDE,点击 "新项目"按钮。
- 选择JavaFX作为框架。
- 在窗口中设置以下内容。
- 名称:可编辑的表视图
- 群组:com.table
- 工件:editabletableview

- 点击'下一步'。
- 在依赖关系部分,设置如下所示的依赖关系,然后点击'完成'按钮。

初始项目结构
生成的应用程序有如下结构。
.
├── src
│ ├── main
│ ├── java
│ ├── com.table.editabletableview
│ ├── HelloApplication.java
│ └── HelloController.java
│ └── module-info.java
│ └── resources
│ └── com.table.editabletableview
│ └── hello-view.fxml
├── editable-tableview.iml
└── pom.xml
新项目结构
- 在
java/com/table/editabletableview路径中创建一个新的文件夹,并将其命名为model。它将保存虚拟数据。 - 在同一路径下创建另一个名为
controller的文件夹。 - 将
HelloController.java文件的位置改为新创建的controller文件夹。这一步可以通过右键单击文件并将其粘贴到新位置来完成。 - 在
model文件夹中,创建一个名为User.java的新文件。
由此产生的文件夹结构看起来如下。
.
├── src
│ ├── main
│ ├── java
│ ├── com. table.editabletableview
│ ├── controller
│ └── HelloController.java
│ └── model
│ └── User.java
│ └── HelloApplication.java
│ └── module-info.java
│ └── resources
│ └── com. table.editabletableview
│ └── hello-view.fxml
├── editable-tableview.iml
└── pom.xml
设置项目、工具和开发环境
为了实现这一点,请做以下工作。
- 打开在
resources/com/table/editabletableview路径中找到的FXML文件。 - IDE会在文件的顶部产生一个提示通知,要求安装
JavaFX SDK。只要允许它,IDE就会自动设置它,并为项目配置它。 - 在靠近状态栏的左下方区域,点击
SceneBuilder选项,查看并使用SceneBuilder开发应用程序。 - 如果这是第一次在机器上使用IDE创建JavaFX项目,它会给出一个安装SceneBuilder的提示通知。只要点击 "安装 "选项,IDE就会下载它并进行设置。
- 如果IDE没有自动加载到SceneBuilder视图,请重新启动IDE。
表的创建和设计
- 在SceneBuilder视图中,只需右键单击
VBox,并选择 "删除 "选项,就可以删除持有Hello按钮的代码。
下面显示的代码将被删除。
这一步可以在这里的Text 视图中查看。
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
fx:controller="com.table.editabletableview.HelloController">
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
</padding>
<Label fx:id="welcomeText"/>
<Button text="Hello!" onAction="#onHelloButtonClick"/>
</VBox>
- 打开控制器,删除以下代码。
@FXML
private Label welcomeText;
@FXML
protected void onHelloButtonClick(){
welcomeText.setText("Welcome to JavaFX Application!");
}
800在HelloApplication.java文件中,将创建的Scene的宽度和高度改为600,如下面一行代码所示。
Scene scene=new Scene(fxmlLoader.load(),800,600);
在这样做的时候,它删除了在项目初始化时生成的默认示例代码。
现在,按以下步骤进行下一步。
- 打开FXML文件,从左侧面板的容器部分下拖放一个
BorderPane到设计页面的中央。 - 在右侧面板下的布局部分,为
BorderPane,使其能与创建的场景相适应,设置如下。Pref Width: 800Pref Height: 600
- 从左侧面板拖放一个
TableView控件到BorderPane的 "中心 "部分。
结果应该是这样的。

- 双击
C1的标题,将其改为id。对C2的标题做同样的操作,将其编辑为name。 - 要添加其他列,请前往
Controls部分并选择TableColumn选项。然后,把它拖放到其他栏目旁边,并适当调整其大小。它的名字将是email。 - 在
TableView中添加另外两列,分别命名为notes和edit。适当地调整大小,使这些列适合TableView。
SceneBuilder 将生成以下代码。
<!--The application's controller is well pointed out-->
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0"
prefWidth="800.0" xmlns="http://javafx.com/javafx/11.0.2" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.table.editabletableview.controller.HelloController">
<center>
<TableView fx:id="table_info" prefHeight="600.0" prefWidth="800.0" BorderPane.alignment="CENTER">
<columns>
<TableColumn fx:id="col_id" prefWidth="75.0" text="id"/>
<TableColumn fx:id="col_name" prefWidth="132.0" text="name"/>
<TableColumn fx:id="col_email" prefWidth="167.0" text="email"/>
<TableColumn fx:id="col_notes" prefWidth="249.0" text="notes"/>
<TableColumn fx:id="col_update" prefWidth="176.0" text="edit"/>
</columns>
</TableView>
</center>
</BorderPane>
注意,控制器的位置在应用程序中被很好地显示出来了。
结果如下。

在TableView上添加数据项
定义用户模型
在'User.java'文件中,做以下工作。
- 添加将用于应用程序的字符串和按钮。
/*Add the strings and buttons to be used in the application*/
String id,name,email,notes;
Button update;
- 生成它们的构造函数。
它看起来应该如下图所示。
/* Constructors */
public User(String id,String name,String email,String notes,Button update){
this.id=id;
this.name=name;
this.email=email;
this.notes=notes;
this.update=update;
}
- 在构造函数中,创建一个函数来制作 "更新"按钮。该按钮在点击时将显示该行的结果。这个按钮允许人们看到结果,因此,确定结果是否符合预期。
在更新按钮点击时。
- 通过调用on获得id
getId() - 通过调用获得姓名
getName() - 通过调用获得电子邮件
getEmail() - 通过调用获取笔记
getNotes()
update.setOnAction(e->{
/* Print the values of the row selected */
ObservableList<User> users=HelloController.table_info_app.getSelectionModel().getSelectedItems();
/* It outputs the value in the terminal */
for(User user:users){
if(user.getUpdate()==update){
System.out.println("id: "+user.getId());
System.out.println("name: "+user.getName());
System.out.println("email: "+user.getEmail());
System.out.println("notes: "+user.getNotes());
}}
});
- 如下所示,在构造函数之外设置获取器和设置器。
/* Getters and setters */
public String getId(){
return id;
}
public void setId(String id){
this.id=id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public String getEmail(){
return email;
}
public void setEmail(String email){
this.email=email;
}
public String getNotes(){
return notes;
}
public void setNotes(String notes){
this.notes=notes;
}
public Button getUpdate(){
return update;
}
这段代码为以下内容设置了获取器和设置器。
- 身份
- 名称
- 电子邮件
- 备注
- 更新按钮
设置控制器
对于'HelloController.java'文件,做以下工作。
- 让这个类实现'Initializable'。
这个类如下所示。
public class HelloController implements Initializable {
/* Line of code */
}
Initializable,是一个JavaFX接口,可以使用初始化方法。
这个方法有助于解决根元素的相对路径。
- 导入将在应用程序中使用的控件。
它显示在下面的代码中。
public static TableView<User> table_info_app;
public static ObservableList<User> data_table;
@FXML
private TableView<User> table_info;
@FXML
private TableColumn<User, String> column_id,column_name,column_email,column_notes;
@FXML
private TableColumn<User, Button> col_update;
上面的代码导入了。
-
表视图:table_info
-
表列:column_id,column_name,column_email,column_notes
-
按钮:col_update
-
在导入的控件下,在控制器的根元素被完全处理后,使用下面的代码来初始化一个控制器。
-
它执行了两个将在后面定义的函数。这些是
initializeCols()和loadData()函数。
@Override
public void initialize(URL url,ResourceBundle resourceBundle){
table_info_app=table_info;
initializeCols();
loadData();
}
注意:
location参数用于解决根对象的相对路径,如果它是已知的,而resources为根对象做本地化。
- 为了更详细地阐述
initializeCols()函数的功能。要指出的是,为特定行单元格输入的值是 "用户 "模型中定义的一组特定数据类型。例如,column_id部分的所有数值是针对所有ID的。
private void initializeCols(){
// User.java ==>> id, name, email, notes;
column_id.setCellValueFactory(new PropertyValueFactory<>("id"));
column_name.setCellValueFactory(new PropertyValueFactory<>("name"));
column_email.setCellValueFactory(new PropertyValueFactory<>("email"));
column_notes.setCellValueFactory(new PropertyValueFactory<>("notes"));
col_update.setCellValueFactory(new PropertyValueFactory<>("update"));
}
如前所述,表中的每一列都与一个数据类型相关。
-
column_idto carry IDs(id) -
column_namefor names(name) -
column_email为电子邮件 -
column_notes用于注释 -
column_update用于更新按钮(button) -
创建另一个名为
loadData()的函数,通过迭代为应用程序创建假数据。把下面的代码复制粘贴到文件中。
private void loadData(){
data_table=FXCollections.observableArrayList();
for(int x=1;x< 12;x++){
/* Generates the data items in the table */
data_table.add(new User(String.valueOf(x),"name "+x,"email "+x,"notes "+x,new Button("update")));
}
table_info.setItems(data_table);
}
上面这段代码产生的结果是记录被存储在系统中。
- 通过'Main'类运行该应用程序。
输出结果应该是这样的。

- 试着双击一个单元格,看看是否可以修改内容。
如前所述,我们只能选择它,但不能编辑其内容。
让表格单元格可编辑
现在,在控制器中,做以下工作。
- 添加一个函数
editableCols(),使单元格有一个Text Field属性,使我们能够显示信息和编辑属性。 - 一旦提交完成,它也会改变单元格的值。当值被改变,并按下回车按钮时,就完成了提交。
private void editableCols(){
column_id.setCellFactory(TextFieldTableCell.forTableColumn());
column_id.setOnEditCommit(e->e.getTableView().getItems().get(e.getTablePosition().getRow()).setId(e.getNewValue()));
column_name.setCellFactory(TextFieldTableCell.forTableColumn());
column_name.setOnEditCommit(e->e.getTableView().getItems().get(e.getTablePosition().getRow()).setName(e.getNewValue()));
column_email.setCellFactory(TextFieldTableCell.forTableColumn());
column_email.setOnEditCommit(e->e.getTableView().getItems().get(e.getTablePosition().getRow()).setEmail(e.getNewValue()));
column_notes.setCellFactory(TextFieldTableCell.forTableColumn());
column_notes.setOnEditCommit(e->e.getTableView().getItems().get(e.getTablePosition().getRow()).setNotes(e.getNewValue()));
/* Allow for the values in each cell to be changable */
table_info.setEditable(true);
}
上面的代码做了以下工作。
- 使得
TableView,所有的单元格都可以编辑。 - 获取特定的单元格是否,对IDs、姓名、电子邮件和备注栏进行双击。
要使用上述函数,请在initializeCols() 函数中调用它,在col_update 行下使用下面这行。
/*Call 'editableCols()' function*/
editableCols();
- 重新运行应用程序并再次尝试。注意,现在更新发生在修改完成后,按回车键提交修改。
在按下更新按钮时,输出被发送到之前配置的终端。

在更新数据库中的内容时,可以获取内容的更新。
结论
表格式是一种非常吸引人的数据表现形式。它很容易理解和使用。编辑和更新内容也是毫不费力。
JavaFX允许人们以表格的形式查看和更新内容。它还允许将样式应用于创建的表格。
到现在为止,读者已经学会了如何。
- 启动一个JavaFX项目。
- 创建表格并设计它们。
- 向表格中添加虚拟数据。
- 使表的数据可编辑。
- 在控制台中获取编辑的内容。
- 操作已编辑的数据。