欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 艺术 > 第三百七十五节 JavaFX教程 - JavaFX表视图

第三百七十五节 JavaFX教程 - JavaFX表视图

2025/3/17 2:03:20 来源:https://blog.csdn.net/2301_78772942/article/details/146220558  浏览:    关键词:第三百七十五节 JavaFX教程 - JavaFX表视图

JavaFX教程 - JavaFX表视图

我们可以使用来自 JavaFX API 的 TableViewTableColumn 和 TableCell 类以表格形式表示数据。

通过实现数据模型和应用单元工厂来填充表中的数据。

表类可以按列排序数据,并在必要时调整列大小。

创建表

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

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

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

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

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

aColumn.setVisible(false).

以下代码创建一个表。

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;public class Main extends Application {public static void main(String[] args) {launch(args);}@Overridepublic void start(Stage primaryStage) {TableView table = new TableView();table.setEditable(true);TableColumn firstNameCol = new TableColumn("First Name");TableColumn lastNameCol = new TableColumn("Last Name");TableColumn emailCol = new TableColumn("Email");table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);emailCol.setVisible(false);StackPane root = new StackPane();root.getChildren().add(table);primaryStage.setScene(new Scene(root, 200, 250));primaryStage.show();}
}

上面的代码生成以下结果。

null

嵌套标头

使用 JavaFX 表视图,我们可以轻松创建嵌套列。

假设我们要将两个子列添加到地址列。

TableColumn cityCol = new TableColumn("City");
TableColumn stateCol = new TableColumn("State");

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

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

完整的源代码

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;public class Main extends Application {public static void main(String[] args) {launch(args);}@Overridepublic void start(Stage primaryStage) {TableView table = new TableView();table.setEditable(true);TableColumn firstNameCol = new TableColumn("First Name");TableColumn lastNameCol = new TableColumn("Last Name");TableColumn addressCol = new TableColumn("Email");table.getColumns().addAll(firstNameCol, lastNameCol, addressCol);TableColumn cityCol = new TableColumn("City");TableColumn stateCol = new TableColumn("State");addressCol.getColumns().addAll(cityCol, stateCol);StackPane root = new StackPane();root.getChildren().add(table);primaryStage.setScene(new Scene(root, 200, 250));primaryStage.show();}
}

上面的代码生成以下结果。

null

添加新行

以下代码显示如何向表视图中添加数据。 创建 JavaFX JavaBean 以保存单个行的值。 表中的每一行代表一个名字为姓氏的人。 JavaFX JavaBean 称为 Person,它有两个字段,名字和姓氏。 Person 为这两个值提供了可绑定的属性。

在 UI 逻辑中,它使用 ObservableList 来保存表视图的值。 ObservableList 中的每个元素都是一个Person对象。

在按钮事件处理程序中,它创建一个新的具有硬编码的名字和姓氏的人,然后添加到 ObservableList

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;public class Main extends Application {private final TableView<Person> table = new TableView<>();private final ObservableList<Person> data =FXCollections.observableArrayList(new Person("A", "B"));final HBox hb = new HBox();public static void main(String[] args) {launch(args);}@Overridepublic void start(Stage stage) {Scene scene = new Scene(new Group());stage.setWidth(450);stage.setHeight(550);TableColumn firstNameCol = new TableColumn("First Name");firstNameCol.setMinWidth(100);firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));TableColumn lastNameCol = new TableColumn("Last Name");lastNameCol.setMinWidth(100);lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));table.setItems(data);table.getColumns().addAll(firstNameCol, lastNameCol);final Button addButton = new Button("Add");addButton.setOnAction((ActionEvent e) -> {data.add(new Person("Z","X"));});hb.getChildren().addAll(addButton);hb.setSpacing(3);final VBox vbox = new VBox();vbox.setSpacing(5);vbox.setPadding(new Insets(10, 0, 0, 10));vbox.getChildren().addAll(table, hb);((Group) scene.getRoot()).getChildren().addAll(vbox);stage.setScene(scene);stage.show();}public static class Person {private final SimpleStringProperty firstName;private final SimpleStringProperty lastName;private Person(String fName, String lName) {this.firstName = new SimpleStringProperty(fName);this.lastName = new SimpleStringProperty(lName);}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);}}
} 

上面的代码生成以下结果。

null

TableView 列排序

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

我们可以通过点击列标题对数据进行排序。第一次单击启用升序排序,第二次点击使得排序顺序降序,第三个点击禁用排序。

默认情况下,不应用排序。

我们可以排序多个列,并在排序操作中指定每个列的优先级。

要对多个列进行排序,请在按住Shift键的同时单击列标题。

我们可以使用 setSortType 方法设置排序首选项我们可以指定升序或降序类型。

以下代码设置排序的降序类型

aColumn.setSortType(TableColumn.SortType.DESCENDING);

我们可以通过从 TableView.sortOrder observable 列表中添加和删除 TableColumn 实例来指定要排序的列。

TableView.sortOrder observable 列中的列的顺序表示排序优先级。 列表中零索引的项目的优先级高于列表中的第一个项目。

要禁止对列进行排序,请调用该列上的 setSortable(false) 方法。

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;public class Main extends Application {private final TableView<Person> table = new TableView<>();private final ObservableList<Person> data =FXCollections.observableArrayList(new Person("A", "B"),new Person("D", "E"));public static void main(String[] args) {launch(args);}@Overridepublic void start(Stage stage) {Scene scene = new Scene(new Group());stage.setWidth(450);stage.setHeight(550);TableColumn firstNameCol = new TableColumn("First Name");firstNameCol.setMinWidth(100);firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));TableColumn lastNameCol = new TableColumn("Last Name");lastNameCol.setMinWidth(100);lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));table.setItems(data);table.getColumns().addAll(firstNameCol, lastNameCol);firstNameCol.setSortType(TableColumn.SortType.DESCENDING);lastNameCol.setSortable(false);final VBox vbox = new VBox();vbox.setSpacing(5);vbox.setPadding(new Insets(10, 0, 0, 10));vbox.getChildren().addAll(table);((Group) scene.getRoot()).getChildren().addAll(vbox);stage.setScene(scene);stage.show();}public static class Person {private final SimpleStringProperty firstName;private final SimpleStringProperty lastName;private Person(String fName, String lName) {this.firstName = new SimpleStringProperty(fName);this.lastName = new SimpleStringProperty(lName);}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);}}
} 

上面的代码生成以下结果。

null

编辑表中的数据

我们可以在表视图中编辑数据。通过调用 setEditable 方法,我们可以启用表内容的编辑。

setCellFactory 方法安装在 TextFieldTableCell 类中定义的文本字段为每个表单元格。

setOnEditCommit 方法更新表单元格,并且数据绑定需要考虑设置数据回到 JavaFX JavaBean,它用作表视图的下划线数据模型。

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.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;public class Main extends Application {private final TableView<Person> table = new TableView<>();private final ObservableList<Person> data =FXCollections.observableArrayList(new Person("A", "B"),new Person("C", "D"));public static void main(String[] args) {launch(args);}@Overridepublic void start(Stage stage) {Scene scene = new Scene(new Group());stage.setWidth(450);stage.setHeight(550);table.setEditable(true);TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");firstNameCol.setMinWidth(100);firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));firstNameCol.setCellFactory(TextFieldTableCell.<Person>forTableColumn());firstNameCol.setOnEditCommit((CellEditEvent<Person, String> t) -> {((Person) t.getTableView().getItems().get(t.getTablePosition().getRow())).setFirstName(t.getNewValue());});TableColumn<Person, String> lastNameCol = new TableColumn<>("Last Name");lastNameCol.setMinWidth(100);lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));lastNameCol.setCellFactory(TextFieldTableCell.<Person>forTableColumn());lastNameCol.setOnEditCommit((CellEditEvent<Person, String> t) -> {((Person) t.getTableView().getItems().get(t.getTablePosition().getRow())).setLastName(t.getNewValue());});table.setItems(data);table.getColumns().addAll(firstNameCol, lastNameCol);final VBox vbox = new VBox();vbox.setSpacing(5);vbox.setPadding(new Insets(10, 0, 0, 10));vbox.getChildren().addAll( table);((Group) scene.getRoot()).getChildren().addAll(vbox);stage.setScene(scene);stage.show();}public static class Person {private final SimpleStringProperty firstName;private final SimpleStringProperty lastName;private Person(String fName, String lName) {this.firstName = new SimpleStringProperty(fName);this.lastName = new SimpleStringProperty(lName);}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);}}
}

上面的代码生成以下结果。

null

表编辑提交事件

当运行上面的代码并双击编辑单元格,我们必须按 Enter 键提交编辑。 如果我们只是双击并键入一些值,并单击单元格外,commit 事件不会运行,旧的值将被填充。

我们可以重新定义焦点更改上的 commit 事件。

/** Copyright (c) 2008, 2014, Oracle and/or its affiliates.* All rights reserved. Use is subject to license terms.** This file is available and licensed under the following license:** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions* are met:**  - Redistributions of source code must retain the above copyright*    notice, this list of conditions and the following disclaimer.*  - Redistributions in binary form must reproduce the above copyright*    notice, this list of conditions and the following disclaimer in*    the documentation and/or other materials provided with the distribution.*  - Neither the name of Oracle nor the names of its*    contributors may be used to endorse or promote products derived*    from this software without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;public class Main extends Application {private final TableView<Person> table = new TableView<>();private final ObservableList<Person> data = FXCollections.observableArrayList(new Person("A", "B"), new Person("C", "D"));public static void main(String[] args) {launch(args);}@Overridepublic void start(Stage stage) {Callback<TableColumn<Person, String>, TableCell<Person, String>> cellFactory = (TableColumn<Person, String> p) -> new EditingCell();Scene scene = new Scene(new Group());stage.setWidth(450);stage.setHeight(550);table.setEditable(true);TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");firstNameCol.setMinWidth(100);firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));firstNameCol.setCellFactory(cellFactory);firstNameCol.setOnEditCommit((CellEditEvent<Person, String> t) -> {((Person) t.getTableView().getItems().get(t.getTablePosition().getRow())).setFirstName(t.getNewValue());});TableColumn<Person, String> lastNameCol = new TableColumn<>("Last Name");lastNameCol.setMinWidth(100);lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));table.setItems(data);table.getColumns().addAll(firstNameCol, lastNameCol);final VBox vbox = new VBox();vbox.setSpacing(5);vbox.setPadding(new Insets(10, 0, 0, 10));vbox.getChildren().addAll(table);((Group) scene.getRoot()).getChildren().addAll(vbox);stage.setScene(scene);stage.show();}class EditingCell extends TableCell<Person, String> {private TextField textField;public EditingCell() {}@Overridepublic void startEdit() {if (!isEmpty()) {super.startEdit();createTextField();setText(null);setGraphic(textField);textField.selectAll();}}@Overridepublic void cancelEdit() {super.cancelEdit();setText((String) getItem());setGraphic(null);}@Overridepublic void updateItem(String item, boolean empty) {super.updateItem(item, empty);if (empty) {setText(null);setGraphic(null);} else {if (isEditing()) {if (textField != null) {textField.setText(getString());}setText(null);setGraphic(textField);} else {setText(getString());setGraphic(null);}}}private void createTextField() {textField = new TextField(getString());textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);textField.focusedProperty().addListener((ObservableValue<? extends Boolean> arg0, Boolean arg1,Boolean arg2) -> {if (!arg2) {commitEdit(textField.getText());}});}private String getString() {return getItem() == null ? "" : getItem().toString();}}public static class Person {private final SimpleStringProperty firstName;private final SimpleStringProperty lastName;private Person(String fName, String lName) {this.firstName = new SimpleStringProperty(fName);this.lastName = new SimpleStringProperty(lName);}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);}}
}

上面的代码生成以下结果。

null

将数据映射添加到表中

我们可以使用 MapValueFactory 类将 Map 数据添加到表中。

/** Copyright (c) 2008, 2014, Oracle and/or its affiliates.* All rights reserved. Use is subject to license terms.** This file is available and licensed under the following license:** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions* are met:**  - Redistributions of source code must retain the above copyright*    notice, this list of conditions and the following disclaimer.*  - Redistributions in binary form must reproduce the above copyright*    notice, this list of conditions and the following disclaimer in*    the documentation and/or other materials provided with the distribution.*  - Neither the name of Oracle nor the names of its*    contributors may be used to endorse or promote products derived*    from this software without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
import java.util.HashMap;
import java.util.Map;
import javafx.application.Application;
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.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.MapValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;public class Main extends Application {public static final String Column1MapKey = "A";public static final String Column2MapKey = "B";public static void main(String[] args) {launch(args);}@Overridepublic 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("Student IDs");label.setFont(new Font("Arial", 20));TableColumn<Map, String> firstDataColumn = new TableColumn<>("Class A");TableColumn<Map, String> secondDataColumn = new TableColumn<>("Class B");firstDataColumn.setCellValueFactory(new MapValueFactory(Column1MapKey));firstDataColumn.setMinWidth(130);secondDataColumn.setCellValueFactory(new MapValueFactory(Column2MapKey));secondDataColumn.setMinWidth(130);TableView tableView = new TableView<>(generateDataInMap());tableView.setEditable(true);tableView.getSelectionModel().setCellSelectionEnabled(true);tableView.getColumns().setAll(firstDataColumn, secondDataColumn);Callback<TableColumn<Map, String>, TableCell<Map, String>>cellFactoryForMap = (TableColumn<Map, String> p) -> new TextFieldTableCell(new StringConverter() {@Overridepublic String toString(Object t) {return t.toString();}@Overridepublic Object fromString(String string) {return string;}});firstDataColumn.setCellFactory(cellFactoryForMap);secondDataColumn.setCellFactory(cellFactoryForMap);final VBox vbox = new VBox();vbox.setSpacing(5);vbox.setPadding(new Insets(10, 0, 0, 10));vbox.getChildren().addAll(label, tableView);((Group) scene.getRoot()).getChildren().addAll(vbox);stage.setScene(scene);stage.show();}private ObservableList<Map> generateDataInMap() {int max = 10;ObservableList<Map> allData = FXCollections.observableArrayList();for (int i = 1; i < max; i++) {Map<String, String> dataRow = new HashMap<>();String value1 = "A" + i;String value2 = "B" + i;dataRow.put(Column1MapKey, value1);dataRow.put(Column2MapKey, value2);allData.add(dataRow);}return allData;}
}

上面的代码生成以下结果。

null

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词