JavaFX向TableView插入数据时出现LoadException的解决求助
JavaFX TableView 填充数据时出现
javafx.fxml.LoadException 的解决方案 问题说明
在给TableView设置数据时触发javafx.fxml.LoadException,移除table.setItems(data)语句后错误消失,但表格无法填充数据。
问题根源
- 静态组件注入失败:控制器中
TableView被声明为static,FXML注入的组件不能是静态成员——FXML会创建控制器实例,静态成员不会被正确注入,导致table为null,调用setItems时抛出空指针,进而引发LoadException。 - 模型类属性实现不符合规范:原模型类的setter方法是重新创建Property对象,而非修改已有Property的值,同时缺少Property访问方法,导致
PropertyValueFactory无法正确绑定数据。
修复步骤
1. 修正控制器中的静态TableView
将控制器里的静态TableView改为非静态:
@FXML TableView<Todo> table; // 移除static修饰符,同时更新类型为规范的Todo类
2. 重构模型类(符合JavaFX属性规范)
修改模型类,提供Property访问方法,并修正setter逻辑:
import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleStringProperty; // 类名首字母大写,符合Java命名规范 public class Todo { private final SimpleIntegerProperty id; private final SimpleStringProperty todo; private final SimpleStringProperty description; private final SimpleStringProperty delete; public Todo(int id, String todo, String description, String delete) { this.id = new SimpleIntegerProperty(id); this.todo = new SimpleStringProperty(todo); this.description = new SimpleStringProperty(description); this.delete = new SimpleStringProperty(delete); } // Property访问方法,供PropertyValueFactory使用 public SimpleIntegerProperty idProperty() { return id; } public SimpleStringProperty todoProperty() { return todo; } public SimpleStringProperty descriptionProperty() { return description; } public SimpleStringProperty deleteProperty() { return delete; } // Getter方法 public Integer getId() { return id.get(); } public String getTodo() { return todo.get(); } public String getDescription() { return description.get(); } public String getDelete() { return delete.get(); } // Setter方法:修改Property的值,而非重新创建对象 public void setId(int id) { this.id.set(id); } public void setTodo(String todo) { this.todo.set(todo); } public void setDescription(String description) { this.description.set(description); } public void setDelete(String delete) { this.delete.set(delete); } }
3. 更新控制器的类型引用与补充方法
同步修改控制器中的类型引用,并补充add方法(原FXML绑定了该方法但未实现):
import java.net.URL; import java.util.ResourceBundle; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.TextArea; import javafx.scene.control.TextField; import javafx.scene.control.cell.PropertyValueFactory; // 控制器类名首字母大写 public class TodoController implements Initializable { @FXML TextField todo; @FXML TextArea description; @FXML TableView<Todo> table; @FXML TableColumn<Todo, Integer> colId; @FXML TableColumn<Todo, String> colTodo; @FXML TableColumn<Todo, String> colDescription; @FXML TableColumn<Todo, String> colDelete; ObservableList<Todo> data = FXCollections.observableArrayList( new Todo(0, "run", "go running", "ejhfue") ); @Override public void initialize(URL location, ResourceBundle resource) { colId.setCellValueFactory(new PropertyValueFactory<>("id")); colTodo.setCellValueFactory(new PropertyValueFactory<>("todo")); colDescription.setCellValueFactory(new PropertyValueFactory<>("description")); colDelete.setCellValueFactory(new PropertyValueFactory<>("delete")); table.setItems(data); // 此时table已被正确注入,不会为空 } // 实现FXML绑定的add方法 @FXML private void add(ActionEvent event) { String todoText = todo.getText(); String descText = description.getText(); if (!todoText.isEmpty()) { int newId = data.size(); data.add(new Todo(newId, todoText, descText, "delete")); // 清空输入框 todo.clear(); description.clear(); } } }
4. 更新FXML的控制器引用
修改FXML文件中的控制器类名(对应重构后的类名):
fx:controller="TodoController"
验证效果
修改完成后运行应用:
table会被FXML正确注入,调用setItems(data)不再抛出异常,表格正常显示初始数据。- 点击ADD按钮可添加新的Todo项到表格中。
内容的提问来源于stack exchange,提问作者YOFTAHE
相关产品推荐
相关产品推荐

