TableView
TableView加载普通JavaBean
定义普通学生实体类
public class Student { private String name; private Integer age; private Double score; private Boolean gender; public Student() { } public Student(String name, Integer age, Double score, Boolean gender) { this.name = name; this.age = age; this.score = score; this.gender = gender; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Double getScore() { return score; } public void setScore(Double score) { this.score = score; } public Boolean getGender() { return gender; } public void setGender(Boolean boy) { gender = boy; } }
创建学生对象,填充可观察列表
// 创建5个学生对象 Student student1 = new Student("张三", 20, 80.0, true); Student student2 = new Student("李四", 21, 90.0, false); Student student3 = new Student("王五", 22, 100.0, true); Student student4 = new Student("赵六", 23, 70.0, false); Student student5 = new Student("钱七", 24, 60.0, true); ObservableList<Student> list = FXCollections.observableArrayList(); list.addAll(student1, student2, student3, student4, student5);
传入list创建TableView
TableView<Student> tableView = new TableView<>(list); tableView.setLayoutX(100); tableView.setLayoutY(100);
构建tableView的每一列数据
TableColumn<Student, String> nameCol = new TableColumn<>("姓名"); nameCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Student, String>, ObservableValue<String>>() { @Override public ObservableValue<String> call(TableColumn.CellDataFeatures<Student, String> cellData) { return new SimpleStringProperty(cellData.getValue().getName()); } }); // 对于数字类型的字段必须,必须使用其抽象类Number定义泛型 TableColumn<Student, Number> ageCol = new TableColumn<>("年龄"); ageCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Student, Number>, ObservableValue<Number>>() { @Override public ObservableValue<Number> call(TableColumn.CellDataFeatures<Student, Number> cellData) { return new SimpleIntegerProperty(cellData.getValue().getAge()); } }); TableColumn<Student, Number> scoreCol = new TableColumn<>("成绩"); scoreCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Student, Number>, ObservableValue<Number>>() { @Override public ObservableValue<Number> call(TableColumn.CellDataFeatures<Student, Number> cellData) { return new SimpleDoubleProperty(cellData.getValue().getScore()); } }); TableColumn<Student, Boolean> isBoyCol = new TableColumn<>("是男生"); isBoyCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Student, Boolean>, ObservableValue<Boolean>>() { @Override public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Student, Boolean> cellData) { return new SimpleBooleanProperty(cellData.getValue().getGender()); } });
另一种写法
// 第二种写法,通过加载属性名称进行加载,内部通过反射调用属性列的getter方法,因此getter方法编写必须符合规范 TableColumn<Student, String> nameCol = new TableColumn<>("姓名"); nameCol.setCellValueFactory(new PropertyValueFactory<>("name")); // 对于数字类型的字段,可以指定其抽象类Number或者它本身所属的类作为泛型 // TableColumn<Student, Number> ageCol = new TableColumn<>("年龄"); // ageCol.setCellValueFactory(new PropertyValueFactory<>("age")); // TableColumn<Student, Number> scoreCol = new TableColumn<>("成绩"); // scoreCol.setCellValueFactory(new PropertyValueFactory<>("score")); TableColumn<Student, Integer> ageCol = new TableColumn<>("年龄"); ageCol.setCellValueFactory(new PropertyValueFactory<>("age")); TableColumn<Student, Double> scoreCol = new TableColumn<>("成绩"); scoreCol.setCellValueFactory(new PropertyValueFactory<>("score")); TableColumn<Student, Boolean> isBoyCol = new TableColumn<>("是男生"); isBoyCol.setCellValueFactory(new PropertyValueFactory<>("isBoy"));
给tableView添加列
tableView.getColumns().add(nameCol); tableView.getColumns().add(ageCol); tableView.getColumns().add(scoreCol); tableView.getColumns().add(isBoyCol);
用于测试的按钮点击事件
button.setOnAction(event -> { if (tableView.getItems().size() > 0) { // 成功删除并移除出界面 tableView.getItems().remove(0); // 成功修改并显示到界面 tableView.getItems().set(3, new Student("REINE", 20, 80.0, true)); // 成功修改但界面不刷新 student1.setName("REINE"); // 必须强制刷新 tableView.refresh(); } else { Alert alert = new Alert(Alert.AlertType.ERROR); alert.setHeaderText("没有数据"); alert.show(); } });
TableView加载监视JavaBean
定义监视学生实体类
public class StudentProperty { private SimpleStringProperty name = new SimpleStringProperty(); private SimpleIntegerProperty age = new SimpleIntegerProperty(); private SimpleDoubleProperty score = new SimpleDoubleProperty(); private SimpleBooleanProperty gender = new SimpleBooleanProperty(); public StudentProperty() { } public StudentProperty(String name, int age, double score, boolean gender) { this.name.set(name); this.age.set(age); this.score.set(score); this.gender.set(gender); } public String getName() { return name.get(); } // 注意每一个监视属性获取其监视属性对象的书写 public SimpleStringProperty nameProperty() { return name; } public void setName(String name) { this.name.set(name); } public int getAge() { return age.get(); } public SimpleIntegerProperty ageProperty() { return age; } public void setAge(int age) { this.age.set(age); } public double getScore() { return score.get(); } public SimpleDoubleProperty scoreProperty() { return score; } public void setScore(double score) { this.score.set(score); } // 注意SimpleBooleanProperty类型getter方法的书写 public boolean isGender() { return gender.get(); } public SimpleBooleanProperty genderProperty() { return gender; } public void setGender(boolean gender) { this.gender.set(gender); } }
创建学生对象,填充可观察列表
// 创建5个学生对象 StudentProperty student1 = new StudentProperty("张三", 20, 80.0, true); StudentProperty student2 = new StudentProperty("李四", 21, 90.0, false); StudentProperty student3 = new StudentProperty("王五", 22, 100.0, true); StudentProperty student4 = new StudentProperty("赵六", 23, 70.0, false); StudentProperty student5 = new StudentProperty("钱七", 24, 60.0, true); ObservableList<StudentProperty> list = FXCollections.observableArrayList(); list.addAll(student1, student2, student3, student4, student5);
传入list创建TableView
TableView<Student> tableView = new TableView<>(list); tableView.setLayoutX(100); tableView.setLayoutY(100);
构建tableView的每一列数据
TableColumn<StudentProperty, String> nameCol = new TableColumn<>("姓名"); nameCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<StudentProperty, String>, ObservableValue<String>>() { @Override public ObservableValue<String> call(TableColumn.CellDataFeatures<StudentProperty, String> cellData) { return cellData.getValue().nameProperty(); } }); // 对于数字类型的字段必须,必须使用其抽象类Number定义泛型 TableColumn<StudentProperty, Number> ageCol = new TableColumn<>("年龄"); ageCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<StudentProperty, Number>, ObservableValue<Number>>() { @Override public ObservableValue<Number> call(TableColumn.CellDataFeatures<StudentProperty, Number> cellData) { return cellData.getValue().ageProperty(); } }); TableColumn<StudentProperty, Number> scoreCol = new TableColumn<>("成绩"); scoreCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<StudentProperty, Number>, ObservableValue<Number>>() { @Override public ObservableValue<Number> call(TableColumn.CellDataFeatures<StudentProperty, Number> cellData) { return cellData.getValue().scoreProperty(); } }); TableColumn<StudentProperty, Boolean> isBoyCol = new TableColumn<>("是男生"); isBoyCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<StudentProperty, Boolean>, ObservableValue<Boolean>>() { @Override public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<StudentProperty, Boolean> cellData) { return cellData.getValue().genderProperty(); } });
另一种写法
// 注意监视对象获取监视属性的写法为xxxProperty(),否则无法监听数据变化同时更新界面 TableColumn<StudentProperty, String> nameCol = new TableColumn<>("姓名"); nameCol.setCellValueFactory(new PropertyValueFactory<>("name")); // 对于数字类型的字段,可以指定其抽象类Number或者它本身所属的类作为泛型 // TableColumn<StudentProperty, Number> ageCol = new TableColumn<>("年龄"); // ageCol.setCellValueFactory(new PropertyValueFactory<>("age")); // TableColumn<StudentProperty, Number> scoreCol = new TableColumn<>("成绩"); // scoreCol.setCellValueFactory(new PropertyValueFactory<>("score")); TableColumn<StudentProperty, Integer> ageCol = new TableColumn<>("年龄"); ageCol.setCellValueFactory(new PropertyValueFactory<>("age")); TableColumn<StudentProperty, Double> scoreCol = new TableColumn<>("成绩"); scoreCol.setCellValueFactory(new PropertyValueFactory<>("score")); // 注意Boolean监视属性getter的写法为isXXX TableColumn<StudentProperty, Boolean> isBoyCol = new TableColumn<>("是男生"); isBoyCol.setCellValueFactory(new PropertyValueFactory<>("gender"));
给tableView添加列
tableView.getColumns().add(nameCol); tableView.getColumns().add(ageCol); tableView.getColumns().add(scoreCol); tableView.getColumns().add(isBoyCol);
用于测试的按钮点击事件
button.setOnAction(event -> { if (tableView.getItems().size() > 0) { // 成功修改并显示到界面 // tableView.getItems().set(3, new StudentProperty("REINE", 20, 80.0, true)); // 成功修改并显示到界面 student1.setName("REINE"); // 成功修改并显示到界面 student2.setAge(14); // 可以得知list中对于的数据也被修改了 list.forEach(System.out::println); } else { Alert alert = new Alert(Alert.AlertType.ERROR); alert.setHeaderText("没有数据"); alert.show(); } });
当tableView中的数据发生改变时,可观察列表list是否能监听到其数据发生的变化
// 对list的某一条数据进行修改时不会触发该监听,除非在创建list时传入了回调函数callback,且修改的属性在callback返回的监视属性数组中才会触发该监听 list.addListener(new ListChangeListener<StudentProperty>() { @Override public void onChanged(Change<? extends StudentProperty> c) { System.out.println("c = " + c); } });
相对于第七点提出的通过传入回调函数callback创建可观察列表的写法
ObservableList<StudentProperty> list = FXCollections.observableArrayList(new Callback<StudentProperty, Observable[]>() { @Override public Observable[] call(StudentProperty param) { // 将每个StudentProperty对象中所有的监视属性返回 return new Observable[]{param.nameProperty(),param.ageProperty(),param.scoreProperty(),param.genderProperty()}; } });