You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX向TableView插入数据时出现LoadException的解决求助

JavaFX TableView 填充数据时出现 javafx.fxml.LoadException 的解决方案

问题说明

在给TableView设置数据时触发javafx.fxml.LoadException,移除table.setItems(data)语句后错误消失,但表格无法填充数据。


问题根源

  1. 静态组件注入失败:控制器中TableView被声明为static,FXML注入的组件不能是静态成员——FXML会创建控制器实例,静态成员不会被正确注入,导致table为null,调用setItems时抛出空指针,进而引发LoadException。
  2. 模型类属性实现不符合规范:原模型类的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 20:53:06