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

Java接收Socket数据时JTable无法实时添加行的正确实现方法

错误原因
  • 核心问题是违反Swing的单线程编程规则:Swing组件的所有创建、数据更新、UI重绘操作都必须在事件派发线程(EDT) 上执行。你的UDP数据接收逻辑运行在独立的工作子线程中,直接在该子线程调用addRow()修改TableModel属于跨线程操作UI,Swing不会正常触发表格的重绘逻辑,这就是行数据追加后界面不生效的根本原因。
  • 隐藏的潜在bug:代码中没有对拆分后的message数组做长度校验,如果收到的UDP数据按逗号拆分后长度不足5,直接访问message[0]到message[4]会抛出数组越界异常,异常被catch块捕获后,addRow()方法根本不会执行。
正确实现方案

核心改动是:在工作线程收到Socket数据后,不要直接操作UI组件,而是把更新表格的逻辑封装为任务,通过SwingUtilities.invokeLater()投递到EDT线程执行,同时补充必要的边界校验。
修正后的run方法代码如下:

@Override
public void run(){
    DatagramSocket aSocket = null;
    try {
        aSocket = new DatagramSocket (6666);
        byte[] buffer = new byte[1000];

        while (true) {
            DatagramPacket request = new DatagramPacket (buffer, buffer.length);
            aSocket.receive (request);
            // 指定字符集避免乱码
            String receiveContent = new String(request.getData(), 0,request.getLength(), StandardCharsets.UTF_8);
            String[] message  = receiveContent.split(",");
            
            // 数组长度校验,过滤格式错误的报文
            if(message.length < 5){
                System.out.println("收到的数据格式不符合要求,跳过:" + receiveContent);
                continue;
            }

            // 将UI更新逻辑投递到EDT线程执行
            final String[] rowData = message;
            SwingUtilities.invokeLater(() -> {
                DefaultTableModel table = (DefaultTableModel) jTable1_liveTable.getModel();
                table.addRow(new Object[]{rowData[0],rowData[1],rowData[2],rowData[3],rowData[4]});
            });
        }   
        
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        // 用完关闭Socket避免端口占用
        if(aSocket != null && !aSocket.isClosed()){
            aSocket.close();
        }
    }
}

补充说明:如果后续需要高频更新表格(比如每秒接收几十上百条数据),可以把多条数据攒成一批再一次性投递到EDT更新,减少EDT线程的调度压力,避免界面卡顿。

内容的提问来源于stack exchange,提问作者Saleh Nayem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 23:21:33