创建表格时我们可以将表格中的每一行(元组)设定为对象,这样子每一行就可以从类中实例化得到,需要了解清楚的是创建表格时必须要创建每一列(字段名),然后类中的每一个属性需要绑定到对应的字段名。
表格的生成过程:实例化类得到对象,对象加入到对象数组,对象数组加入到数据模型,数据模型加入表格。
为什么不直接将对象加入到数据模型呢???因为这是一个小技巧!!!后面会讲到。
一. 生成表格
1.创建类(用于实例化对象,每一个对象使一个元组,元组集合就是表格)
注意!!!如果你想在元组后面加上“编辑”,“删除”等控制元件,最好不要添加到类中。
我假设创建Employee类(每个数据都是属性,因为只有属性可以绑定到表格中)
public class Employee {
//定义数据域,都为字符型或者数值型的属性
private SimpleStringProperty employeeNum; //职工号
private SimpleStringProperty name; //姓名
private SimpleStringProperty sex; //性别
private SimpleIntegerProperty age; //年龄
private SimpleStringProperty education; //学历
private SimpleIntegerProperty salary;//薪水
private SimpleStringProperty address; //地址
private SimpleStringProperty telephone; //电话
private SimpleIntegerProperty workAge; //工龄
private SimpleStringProperty position; //职位
}
2.创建列,每列的每个元素都是Employee类实例化的对象里面的属性类型,除了最后一列的删除可选框。后面对应表格的列的字段名字
TableColumn<Employee,String> col1 = new TableColumn<>("职工号");//创建表格中的列名
TableColumn<Employee,String> col2 = new TableColumn("姓名");
TableColumn<Employee,String> col3 = new TableColumn("性别");
TableColumn<Employee,Integer> col4 = new TableColumn("年龄");
TableColumn<Employee,String> col5 = new TableColumn("学历");
TableColumn<Employee,Integer> col6 = new TableColumn("工资");
TableColumn<Employee,String> col7 = new TableColumn("地址");
TableColumn<Employee,String> col8 = new TableColumn("电话");
TableColumn<Employee,Integer> col9 = new TableColumn("工龄");
TableColumn<Employee,String> col10 = new TableColumn("职位");
TableColumn col11 = new TableColumn("删除");
``
3.每列绑定到Employee对象的属性
本来想在类中设定删除可选框,但是代码调试到后面,发现行不通,所以我选择把删除可选框这一列单独拿出来,判断元组是否为空,如果不为空,我就加入删除可选框。
//单元格属性的绑定,类里面的属性关联到表格中的每一列
col1.setCellValueFactory( new PropertyValueFactory<>("employeeNum"));
col2.setCellValueFactory( new PropertyValueFactory<>("name"));
col3.setCellValueFactory( new PropertyValueFactory<>("sex"));
col4.setCellValueFactory( new PropertyValueFactory<>("age"));
col5.setCellValueFactory( new PropertyValueFactory<>("education"));
col6.setCellValueFactory( new PropertyValueFactory<>("salary"));
col7.setCellValueFactory( new PropertyValueFactory<>("address"));
col8.setCellValueFactory( new PropertyValueFactory<>("telephone"));
col9.setCellValueFactory( new PropertyValueFactory<>("workAge"));
col10.setCellValueFactory( new PropertyValueFactory<>("position"));
// col11.setCellValueFactory( new PropertyValueFactory<>("checkbox"));//本来设定为删除可选框
table.getColumns().addAll(col1, col2, col3,col4,col5,col6,col7,col8,col9,col10,col11);//将列加入表格中
//删除可选框功能的实现
col11.setCellFactory((col) -> {
TableCell<Employee,String> cell = new TableCell<Employee, String>() {
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
this.setText(null);
this.setGraphic(null);
if (!empty) { //判断每一行是否为空,不为空就添加单选框
CheckBox checkbox = new CheckBox();
this.setGraphic(checkbox);
checkbox.selectedProperty().addListener((obVal, oldVal, newVal) -> {
if (newVal) {
// 添加选中时执行的代码
System.out.println("第" + (this.getIndex()+1)+ "行被选中!");
// 获取当前单元格的对象
// this.getItem();
}
});
}
}
}; return cell;
});
4.本来是可以直接创建数据模型,在数据模型中初始化类,然后把数据模型加入表格。这样子在后面的可视化界面生成的时候会出现问题,比如单击按钮事件时候,并不会清除原来的表格,而是表格累加,问题的原因是你没有在数据模型中清除对象,每次触发事件时生成的新对象重新加入到数据模型中的对象数组中,呈现表格;解决问题的方法就是每次触发事件都清除数组对象。
所以需要创建数组对象,数据模型和表格。数组对象加入到数据模型,数据模型加入表格。
TableView<Employee> table = new TableView<>();//创建包含职工对象的表格
ObservableList<Employee> data =null; //定义数据模型,数据模型中包含数据,然后把数据关联到表格中
ArrayList<Employee> emp = new ArrayList<>();//创建对象数组
emp.add(new Employee(id,name,gender,age,education,salary,addr,phone,workage,position));//对象数组中加入对象
data = FXCollections.observableArrayList(emp);//将对象数组加入数据模型中
table.setItems(data);//数据模型加入表格中
emp.removeAll(emp);//中间过渡,对象数组清空,但是数据模型date还有数据,表格table也有数据
二. 表格的修改功能
这个功能的实现必须要知道基本机制,首先是选择表格中的某个元组的某个框,然后你输入字段或者数值,这一行的对象接收你输入的东西,然后利用修改器进行修改,说到这里就不得不提,Employee类这个对象的属性修改器是会返回属性值的!!!因为返回属性值之后还得赋值给你修改的这个框!!!给大家看一下我的Employee类的属性修改器。这里提一下,修改字符型和数值型的代码是不一样的,然后修改数值型使用Callback方法,我因为导入错误的包无法使用,真的是不应该,大家小心。
public String getEmployeeNum() { //职工号
return employeeNum.get(); //属性的get()方法返回值
}
public String setEmployeeNum(String employeeNum) {
this.employeeNum.set(employeeNum); //属性的set()设置值
return employeeNum;//返回数值,用于修改
}
public String getName() { //姓名
return name.get();
}
public String setName(String name) {
this.name.set(name);
return name;//返回字符,用于修改功能
}
public int getAge(){ //年龄
return age.get();
}
public int setAge(int age) {
this.age.set(age);
return age;
}
1.修改字段是字符型。
col1.setCellFactory(TextFieldTableCell.<Employee>forTableColumn());
col1.setOnEditCommit( (CellEditEvent<Employee, String> t) -> {
//获得输入t的字符,并将字符传递给Employee对象的修改器,修改相应的数值,并返回属性值!!!
String employeeNum = ( (Employee)t.getTableView().getItems().get(t.getTablePosition().getRow())).setEmployeeNum(t.getNewValue());});
2.修改字段是数值型。
//服务于每列的元素修改,修改的是Integer类型,则使用Callback方法,导入相应的包!!!
col4.setCellFactory(new Callback<TableColumn<Employee, Integer>, TableCell<Employee, Integer>>() {
public TableCell<Employee, Integer> call(TableColumn<Employee, Integer> param) {
TextFieldTableCell<Employee, Integer> cell = new TextFieldTableCell<>(new IntegerStringConverter());
return cell;}});
col4.setOnEditCommit( (CellEditEvent<Employee, Integer> t) -> { //每列的元素都是Employee 的Integer对象
//获得输入t的数值,并将数字化传递给Employee对象的修改器,修改相应的数值
int age = ( (Employee)t.getTableView().getItems().get(t.getTablePosition().getRow())).setAge(t.getNewValue());});