我们可以使用来自 JavaFX API 的 TableView,TableColumn 和 TableCell 类以表格形式表示数据。
通过实现数据模型和应用单元工厂来填充表中的数据。
表类可以按列排序数据,并在必要时调整列大小。

创建表

表控件是通过实例化 TableView 类创建的。

  1. TableView table = new TableView();
  2. table.setEditable(true);

然后使用 TableColumn 类创建三个列。TableView 类的 getColumns 方法将创建的列添加到表中。

  1. TableColumn firstNameCol = new TableColumn("First Name");
  2. TableColumn lastNameCol = new TableColumn("Last Name");
  3. TableColumn emailCol = new TableColumn("Email");
  4. table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);

我们可以通过调用 setVisible 方法隐藏列。

  1. aColumn.setVisible(false).

以下代码创建一个表。

  1. import javafx.application.Application;
  2. import javafx.scene.Scene;
  3. import javafx.scene.control.TableColumn;
  4. import javafx.scene.control.TableView;
  5. import javafx.scene.layout.StackPane;
  6. import javafx.stage.Stage;
  7. public class Main extends Application {
  8. public static void main(String[] args) {
  9. launch(args);
  10. }
  11. @Override
  12. public void start(Stage primaryStage) {
  13. TableView table = new TableView();
  14. table.setEditable(true);
  15. TableColumn firstNameCol = new TableColumn("First Name");
  16. TableColumn lastNameCol = new TableColumn("Last Name");
  17. TableColumn emailCol = new TableColumn("Email");
  18. table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
  19. emailCol.setVisible(false);
  20. StackPane root = new StackPane();
  21. root.getChildren().add(table);
  22. primaryStage.setScene(new Scene(root, 200, 250));
  23. primaryStage.show();
  24. }
  25. }

image.png

嵌套标头

使用 JavaFX 表视图,我们可以轻松创建嵌套列。
假设我们要将两个子列添加到地址列。

  1. TableColumn cityCol = new TableColumn("City");
  2. TableColumn stateCol = new TableColumn("State");

然后我们将新创建的列添加到地址列。

  1. addressCol.getColumns().addAll(cityCol, stateCol);

完整的源代码

  1. import javafx.application.Application;
  2. import javafx.scene.Scene;
  3. import javafx.scene.control.TableColumn;
  4. import javafx.scene.control.TableView;
  5. import javafx.scene.layout.StackPane;
  6. import javafx.stage.Stage;
  7. public class Main extends Application {
  8. public static void main(String[] args) {
  9. launch(args);
  10. }
  11. @Override
  12. public void start(Stage primaryStage) {
  13. TableView table = new TableView();
  14. table.setEditable(true);
  15. TableColumn firstNameCol = new TableColumn("First Name");
  16. TableColumn lastNameCol = new TableColumn("Last Name");
  17. TableColumn addressCol = new TableColumn("Email");
  18. table.getColumns().addAll(firstNameCol, lastNameCol, addressCol);
  19. TableColumn cityCol = new TableColumn("City");
  20. TableColumn stateCol = new TableColumn("State");
  21. addressCol.getColumns().addAll(cityCol, stateCol);
  22. StackPane root = new StackPane();
  23. root.getChildren().add(table);
  24. primaryStage.setScene(new Scene(root, 200, 250));
  25. primaryStage.show();
  26. }
  27. }

image.png

动态添加新行

以下代码显示如何向表视图中添加数据。 创建 JavaFX JavaBean 以保存单个行的值。 表中的每一行代表一个名字为姓氏的人。 JavaFX JavaBean 称为 Person,它有两个字段,名字和姓氏。 Person 为这两个值提供了可绑定的属性。
在 UI 逻辑中,它使用 ObservableList 来保存表视图的值。 ObservableList 中的每个元素都是一个Person对象。
在按钮事件处理程序中,它创建一个新的具有硬编码的名字和姓氏的人,然后添加到 ObservableList。

  1. import javafx.application.Application;
  2. import javafx.collections.FXCollections;
  3. import javafx.collections.ObservableList;
  4. import javafx.event.ActionEvent;
  5. import javafx.geometry.Insets;
  6. import javafx.scene.Group;
  7. import javafx.scene.Scene;
  8. import javafx.scene.control.Button;
  9. import javafx.scene.control.TableColumn;
  10. import javafx.scene.control.TableView;
  11. import javafx.scene.control.cell.PropertyValueFactory;
  12. import javafx.scene.layout.HBox;
  13. import javafx.scene.layout.VBox;
  14. import javafx.stage.Stage;
  15. public class JavaFx02 extends Application {
  16. public static void main(String[] args) {
  17. launch(args);
  18. }
  19. @Override
  20. public void start(Stage stage) {
  21. Group root = new Group();
  22. Scene scene = new Scene(root,450,550);
  23. TableView<Person> table = new TableView<>();
  24. ObservableList<Person> data = FXCollections.observableArrayList(new Person("A", "B"));
  25. table.setItems(data);
  26. TableColumn firstNameCol = new TableColumn("First Name");
  27. firstNameCol.setMinWidth(100);
  28. firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
  29. TableColumn lastNameCol = new TableColumn("Last Name");
  30. lastNameCol.setMinWidth(100);
  31. lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));
  32. table.getColumns().addAll(firstNameCol, lastNameCol);
  33. Button addButton = new Button("Add");
  34. addButton.setOnAction((ActionEvent e) -> {
  35. data.add(new Person("Z","X"));
  36. });
  37. HBox hb = new HBox();
  38. hb.getChildren().addAll(addButton);
  39. hb.setSpacing(3);
  40. VBox vbox = new VBox();
  41. vbox.setSpacing(5);
  42. vbox.setPadding(new Insets(10));
  43. vbox.getChildren().addAll(table, hb);
  44. root.getChildren().addAll(vbox);
  45. stage.setScene(scene);
  46. stage.show();
  47. }
  48. public static class Person {
  49. private String firstName;
  50. private String lastName;
  51. public Person(){}
  52. public Person(String firstName,String lastName ){
  53. this.firstName = firstName;
  54. this.lastName = lastName;
  55. }
  56. public String getFirstName() {
  57. return firstName;
  58. }
  59. public void setFirstName(String firstName) {
  60. this.firstName = firstName;
  61. }
  62. public String getLastName() {
  63. return lastName;
  64. }
  65. public void setLastName(String lastName) {
  66. this.lastName = lastName;
  67. }
  68. }
  69. }

image.png

行中添加按钮、排序

TableView 类具有列的内置排序功能。

  1. aColumn.setSortType(TableColumn.SortType.DESCENDING);
  1. import javafx.application.Application;
  2. import javafx.beans.value.ObservableValue;
  3. import javafx.collections.FXCollections;
  4. import javafx.collections.ObservableList;
  5. import javafx.geometry.Insets;
  6. import javafx.scene.Group;
  7. import javafx.scene.Scene;
  8. import javafx.scene.control.Button;
  9. import javafx.scene.control.TableCell;
  10. import javafx.scene.control.TableColumn;
  11. import javafx.scene.control.TableView;
  12. import javafx.scene.control.cell.PropertyValueFactory;
  13. import javafx.scene.layout.VBox;
  14. import javafx.stage.Stage;
  15. import javafx.util.Callback;
  16. public class JavaFx01 extends Application {
  17. public static void main(String[] args) {
  18. launch();
  19. }
  20. @Override
  21. public void start(Stage stage) {
  22. Group root = new Group();
  23. Scene scene = new Scene(root,450,550);
  24. TableView<Person> table = new TableView<>();
  25. ObservableList<Person> data =FXCollections.observableArrayList(new Person("A", "B"),new Person("D", "E"));
  26. table.setItems(data);
  27. TableColumn firstNameCol = new TableColumn("First Name");
  28. firstNameCol.setMinWidth(100);
  29. firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
  30. TableColumn lastNameCol = new TableColumn("Last Name");
  31. lastNameCol.setMinWidth(100);
  32. lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));
  33. TableColumn<Person,String> operationCol = new TableColumn("操作");
  34. lastNameCol.setMinWidth(100);
  35. operationCol.setCellFactory(new Callback<TableColumn<Person, String>, TableCell<Person, String>>() {
  36. @Override
  37. public TableCell<Person, String> call(TableColumn<Person, String> personStringTableColumn) {
  38. Button btn = new Button("删除");
  39. TableCell<Person,String> cell = new TableCell<Person,String>(){
  40. @Override
  41. protected void updateItem(String item, boolean empty) {
  42. super.updateItem(item, empty);
  43. if (empty) {
  44. setGraphic(null);
  45. setText(null);
  46. } else {
  47. btn.setOnAction(actionEvent->{
  48. Person person = getTableView().getItems().get(getIndex());
  49. System.out.println(person.firstName);
  50. System.out.println(person.lastName);
  51. System.out.println("删除....");
  52. });
  53. setGraphic(btn);//设置按钮
  54. setText(null);//清空文本
  55. }
  56. }
  57. };
  58. return cell;
  59. }
  60. });
  61. table.getColumns().addAll(firstNameCol, lastNameCol,operationCol);
  62. firstNameCol.setSortType(TableColumn.SortType.DESCENDING);
  63. lastNameCol.setSortable(false);
  64. VBox vbox = new VBox();
  65. vbox.setSpacing(5);
  66. vbox.setPadding(new Insets(10, 0, 0, 10));
  67. vbox.getChildren().addAll(table);
  68. root.getChildren().addAll(vbox);
  69. stage.setScene(scene);
  70. stage.show();
  71. }
  72. public static class Person {
  73. private String firstName;
  74. private String lastName;
  75. public Person(){}
  76. public Person(String firstName,String lastName ){
  77. this.firstName = firstName;
  78. this.lastName = lastName;
  79. }
  80. public String getFirstName() {
  81. return firstName;
  82. }
  83. public void setFirstName(String firstName) {
  84. this.firstName = firstName;
  85. }
  86. public String getLastName() {
  87. return lastName;
  88. }
  89. public void setLastName(String lastName) {
  90. this.lastName = lastName;
  91. }
  92. }
  93. }

image.png