JavaFX整合Hibernate时TableColumn.setCellValueFactory触发空指针异常
问题原因
你遇到的空指针是@FXML注解的控件注入时机不对导致的:JavaFX中所有@FXML标注的控件字段,只有在FXMLLoader完成FXML文件加载、执行完Controller的initialize()方法之后才会完成赋值。如果你在Controller构造方法中、或是FXMLLoader.load()执行完成前就调用了getAllData()方法,此时id、firstname、lastname这些字段还处于未赋值的null状态,调用方法自然会抛出空指针。
修复方案
1. 拆分绑定逻辑和数据加载逻辑
将固定的单元格值工厂绑定逻辑移到initialize()方法中,该方法会在所有FXML控件注入完成后自动被JavaFX调用,getAllData()仅负责数据加载即可,修改后的Controller代码如下:
@FXML private TableView<Person> table; @FXML private TableColumn<Person, Integer> id; @FXML private TableColumn<Person, String> firstname; @FXML private TableColumn<Person, String> lastname; private final ObservableList<Person> person = FXCollections.observableArrayList(); // 该方法会在FXML控件注入完成后自动执行 @FXML public void initialize() { id.setCellValueFactory(new PropertyValueFactory<>("id")); firstname.setCellValueFactory(new PropertyValueFactory<>("firstName")); lastname.setCellValueFactory(new PropertyValueFactory<>("lastName")); table.setItems(person); } void getAllData() { // 先清空原有数据避免重复添加 person.clear(); List<Person> personList = personService.getPerson(); person.addAll(personList); }
2. 调整getAllData()调用时机
在加载FXML的逻辑中,必须等FXMLLoader.load()执行完成后,再获取Controller实例调用数据加载方法,示例代码如下:
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/forms/FormX.fxml")); // 执行load方法后,FXML控件注入完成,initialize方法也执行完毕 Parent root = fxmlLoader.load(); Controller controller = fxmlLoader.getController(); // 此时调用数据加载方法不会出现空指针 controller.getAllData();
可选检查项
如果修改后仍有问题,可逐一核对以下配置:
- 确认Controller的全类名和FXML中
fx:controller="controller.Controller"声明完全一致,包名、类名大小写无错误 - 确认FXML中
TableColumn的fx:id属性和Controller中对应字段名完全匹配 - 确认
personService已正确实例化,避免后续调用时出现空指针
内容的提问来源于stack exchange,提问作者Bisaya Coding
相关产品推荐
相关产品推荐

