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

每秒更新JTable值时偶发NullPointerException异常的解决求助

Java Swing JTable定时更新偶发空指针异常解决方案

根本原因

你遇到的偶发空指针是三个典型的Swing开发错误共同导致的:

  • 线程违规操作:Swing的所有UI相关逻辑(包括修改UI绑定的数据模型、触发UI更新)必须运行在AWT事件调度线程(EDT)中。你当前使用的TimerTask是后台工作线程,直接在该线程中修改表格绑定的数组、触发UI刷新,会导致EDT在绘制单元格的过程中,数据被后台线程中途修改,出现状态不一致,进而触发空指针。
  • 错误调用updateUI():该方法是Swing组件用于响应外观(Look&Feel)变更的专用方法,完全不是用来刷新表格内容的。频繁调用该方法会强制重置组件UI状态,是触发空指针的直接诱因。
  • 未使用标准TableModel通知机制:直接修改绑定的二维数组,JTable无法精准感知单元格变更,只能通过全量重绘刷新,效率低且容易出现状态冲突。

修复方案

步骤1:重构表格数据管理逻辑

改用DefaultTableModel管理表格数据,删掉自定义的二维数组和错误的updateUI()调用:

// 改用DefaultTableModel管理数据,header保持你原有的列头定义即可
private DefaultTableModel tableModel = new DefaultTableModel(new Object[6][5], header);
private JTable tblProcesses = new JTable(tableModel);

public Object getCell(int row, int col) {
    return tableModel.getValueAt(row, col);
}

public void setCell(int row, int col, Object object) {
    // 修改模型后会自动通知JTable仅刷新对应单元格,无需手动调用刷新方法
    tableModel.setValueAt(object, row, col);
}

步骤2:改用Swing专用定时器

替换TimerTask为javax.swing.Timer,该定时器的回调默认运行在EDT线程,从根源避免线程安全问题:

// 1000为触发间隔,单位毫秒,每秒执行一次
Timer processTimer = new Timer(1000, e -> {
    for (int i = 0; i < 6; i++) {
        int currentVal = (int) mainTable.getCell(i, 1);
        mainTable.setCell(i, 1, currentVal + 1);
    }
});
// 启动定时器
processTimer.start();

如果确实需要保留TimerTask实现,必须将UI操作投递到EDT执行:

TimerTask processTimer = new TimerTask() {
    @Override
    public void run() {
        // 将UI操作投递到EDT线程执行
        SwingUtilities.invokeLater(() -> {
            for (int i = 0; i < 6; i++) {
                int currentVal = (int) mainTable.getCell(i, 1);
                mainTable.setCell(i, 1, currentVal + 1);
            }
        });
    }
};

补充注意事项

初始化表格时请提前给第1列所有行设置初始数值(比如0),避免强转int时遇到null触发空指针。

内容的提问来源于stack exchange,提问作者Smooth Researcher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 18:30:05