javaFX——TableView的使用

本文详细介绍如何在JavaFX中使用TableView组件进行数据展示、编辑及监听单元格修改。包括实体类定义、ObservableList绑定、单元格编辑及事件监听等关键步骤。

一、插入数据

比如我想做这样的一个学生表
在这里插入图片描述
1. 首先定义出表格对应的实体类,包括getter和setter方法,以及SimpleStringProperty属性和对应的Property() 方法(这个属性和方法是必须的)
要注意Perperty()方法的命名,一定要按照 “SimpleStringProperty变量名”+Property() 这样的格式命名,而且该变量名必须要与实体类中定义的SimpleStringProperty属性一致。比如图中定义了private SimpleStringProperty tutorIdString;,那么对应的方法必须是public SimpleStringProperty tutorIdStringProperty()
定义这个SimpleStringProperty是TableView展示数据的时候需要取到每个实体的值并用字符串展示。
PS: SimpleStringProperty属性记得实例化。可能你的setter方法没调用到所以没实例化到,因此你也可以放在你的构造方法。

public class Student {
	private int id;
	private String name;
	private int tutorId;
	private SimpleStringProperty idString;
	private SimpleStringProperty nameString;
	private SimpleStringProperty tutorIdString;
	
	public Student(String name) {
		this.name = name;
	}
	
	public int getId() {
		return id;
	}
	
	public void setId(int id) {
		this.id=id;
		this.idString = new SimpleStringProperty(String.valueOf(id));
	}
	
	public SimpleStringProperty idStringProperty() {
		return idString;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name=name;
		this.nameString = new SimpleStringProperty(name);
	}
	
	public SimpleStringProperty nameStringProperty() {
		return nameString;
	}
	
	public int getTutorId() {
		return tutorId;
	}
	
	public void setTutorId(int tutorId) {
		this.tutorId=tutorId;
		this.tutorIdString = new SimpleStringProperty(String.valueOf(tutorId));
	}
	
	public SimpleStringProperty tutorIdStringProperty() {
		return tutorIdString;
	}
}

2. 然后需要定义一个ObservableList作为绑定TableView的里面的数据。

private ObservableList<Student> students = FXCollections.observableArrayList();

3. 将TableView与ObservableList绑定起来,并设置每一列需要获取的数据的名字,也就是在实体类中定义的SimpleStringProperty属性的名字。也就是调用对应的Property()方法了,这是根据属性名来调用方法,所以就知道为什么这个Property()方法要按照上面说的那种方式命名了。

idCol.setCellValueFactory(new PropertyValueFactory("idString"));
nameCol.setCellValueFactory(new PropertyValueFactory("nameString"));
tidCol.setCellValueFactory(new PropertyValueFactory("tutorIdString"));
allStuTable.setItems(students);

二、编辑单元格

1. 设置TableView为Editable。这个很简单,如果你有SceneBulider插件,就直接在里面设置就好。或者可以使用代码的方式:allStuTable.setEditable(true);
2. 使用下面的代码。作用是把这一列的单元格当作TextField来使用,也就是可以编辑单元格的内容了。

nameCol.setCellFactory(TextFieldTableCell.forTableColumn());

三、监听并获取编辑的单元格的值

按照下面的代码可设置单元格编辑事件。在下面的handler方法中,可通过getOldValue()getNewValue() 方法获取单元格编辑前后的值。
补充一下其他方法,还可以通过getRowValue()获取编辑的单元格的行号(默认从0开始);通过getTablePosition().getColumn()获取列号(默认从0开始)。

nameCol.setOnEditCommit(  //监听并获取修改的单元格的值
    new EventHandler<TableColumn.CellEditEvent>() {
        @Override 
        public void handle(TableColumn.CellEditEvent t) {
            //在这里面设置监听触发事件
            String oldValue = t.getOldValue();  //获取编辑前单元格的值
            String newValue = t.getNewValue();  //获取编辑后单元格的值
        }
    });

PS: 如果获取编辑的单元格的相同行中其它单元格的值,可通过下面的代码:

idCol.getCellObservableValue(t.getRowValue()).getValue();

idCol是另外的TableColumn的变量名,这个方法也是在上面的handle方法中使用。
当然,你也可以通过与这个TableView绑定的ObservableList的实体中来获取其它的值,逐个遍历匹对,但是如果遇到同列同值的数据,处理起来可能有点麻烦。
 
TableView的使用说到这里,对于一些简单的操作应该是没有问题的啦。

### JavaFX TableView 使用 `Map` 参数 在JavaFX中,通常建议使用自定义的数据模型类而不是直接使用`Map`来填充`TableView`。然而,如果确实需要使用`Map`作为数据源,则可以通过适配器模式或者通过实现特定的方法使`TableView`能够理解并展示这些键值对。 对于希望基于`Map<String, Object>`结构显示表格的情况,一种常见做法是创建一个辅助类或内部静态类用于转换每条记录到适合`PropertyValueFactory`使用的格式[^3]。另一种方式是在设置单元格工厂(`setCellValueFactory`)时动态获取对应的映射项: ```java // 假设每一行对应于一个 Map.Entry<String,Object> ObservableList<Map.Entry<String,?>> items = FXCollections.observableArrayList(map.entrySet()); TableColumn<Map.Entry<String,?>, String> keyCol = new TableColumn<>("Key"); keyCol.setCellValueFactory(cellData -> Bindings.createStringBinding( () -> cellData.getValue().getKey(), cellData.getValue() )); TableColumn<Map.Entry<String,?>, Object> valueCol = new TableColumn<>("Value"); valueCol.setCellValueFactory(cellData -> { SimpleObjectProperty<Object> prop = new SimpleObjectProperty<>(cellData.getValue().getValue()); return prop; }); tableView.getColumns().addAll(keyCol, valueCol); tableView.setItems(items); ``` 当面对更复杂的场景——即整个表由多个`Map`组成时,可以考虑构建一个封装了`Map`的对象列表,并为每个属性提供getter方法以便与`PropertyValueFactory`兼容[^4]。 值得注意的是,在实际开发过程中应尽可能遵循面向对象设计原则,优先选用专门化的实体类而非泛型容器如`Map`来表示业务逻辑中的概念[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值