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

JTable展示CSV数据异常求助:数据未正常显示且报数组越界

问题排查与解决方案

我来帮你解决这两个核心问题:ArrayIndexOutOfBoundsException异常,以及CSV数据无法正确显示在JTable中的问题。

1. 数组越界异常(java.lang.ArrayIndexOutOfBoundsException: 16)

问题原因

你的MiModel表格模型固定了18列(对应columnNames数组的长度),但CSV文件中存在某一行拆分后的数组长度不足18。比如某一行只有16个元素,当表格尝试访问第17个索引(索引从0开始,对应第18列)时,就会触发数组越界异常。

解决方案

我们可以通过两个步骤来解决:一是在添加CSV数据时,确保每一行的元素数量与表格列数一致;二是在getValueAt方法中添加边界检查,双重保险避免越界。

修改MiModel类的代码:

class MiModel extends AbstractTableModel {
    private String [] columnNames = {"1","2","3","4","5","6","7","8","9","10", "11","12","13","14","15","16","17","18"};
    private ArrayList<String[]>Data = new ArrayList<>();

    public void AddCSVData(ArrayList<String[]> DataIn){
        ArrayList<String[]> processedData = new ArrayList<>();
        int targetColCount = columnNames.length;
        
        // 处理每一行,补全不足的列
        for(String[] row : DataIn){
            String[] processedRow = new String[targetColCount];
            // 复制已有数据
            System.arraycopy(row, 0, processedRow, 0, Math.min(row.length, targetColCount));
            // 不足的列填充空字符串
            for(int i = row.length; i < targetColCount; i++){
                processedRow[i] = "";
            }
            processedData.add(processedRow);
        }
        
        this.Data = processedData;
        this.fireTableDataChanged();
    }

    @Override
    public int getColumnCount(){
        return columnNames.length;
    }

    @Override
    public int getRowCount(){
        return Data.size();
    }

    @Override
    public String getColumnName(int col){
        return columnNames[col];
    }

    @Override
    public Object getValueAt(int row, int col){
        // 边界检查,避免越界
        if(row >= Data.size() || col >= Data.get(row).length){
            return "";
        }
        return Data.get(row)[col];
    }
}

2. CSV数据未正确显示(丢失行数据)

问题原因

在CSVFile的ReadCSVFile方法中,你每次循环调用了两次brd.readLine():第一次在while(brd.readLine()!= null)的条件判断中读取了一行,但没有保存;第二次在循环体内又读取下一行,导致一半的行数据被跳过,自然无法在表格中显示完整。

解决方案

修改ReadCSVFile方法,只调用一次readLine()并保存结果,同时注意关闭流避免资源泄漏:

public class CSVFile {
    public ArrayList<String[]> ReadCSVFile(File DataFile){
        ArrayList<String[]> Rs = new ArrayList<>(); // 移到方法内,避免多次调用时数据残留
        try{
            BufferedReader brd = new BufferedReader (new FileReader(DataFile));
            String st;
            // 一次读取一行,直到返回null
            while((st = brd.readLine())!= null){
                // 注意:如果CSV字段包含逗号(如带引号的字段),split(",")会出错,建议用专业CSV库
                String[] oneRow = st.split(",");
                Rs.add(oneRow);
                System.out.println(Arrays.toString(oneRow));
            }
            brd.close(); // 关闭流
        }catch(Exception ex){
            String errmsg = ex.getMessage();
            System.out.println("File not Found: "+errmsg);
        }
        return Rs;
    }
}

额外优化建议

  • 避免空指针异常:在actionPerformed方法中,要先判断用户是否确认选择了文件,否则getSelectedFile()会返回null:
public void actionPerformed(ActionEvent Event) {
    JFileChooser file_chooser = new JFileChooser();
    int returnVal = file_chooser.showOpenDialog(null);
    // 检查用户是否确认选择文件
    if(returnVal == JFileChooser.APPROVE_OPTION){
        CSVFile Rd = new CSVFile();
        MiModel NewModel = new MiModel();
        this.Table.setModel(NewModel);
        File DataFile = file_chooser.getSelectedFile();
        ArrayList<String[]> rs2 = Rd.ReadCSVFile(DataFile);
        NewModel.AddCSVData(rs2);
        System.out.println("Rows: " +NewModel.getRowCount());
        System.out.println("Cols: " +NewModel.getColumnCount());
    }
}
  • 专业CSV解析:手动用split(",")无法处理带引号的字段(比如字段内容包含逗号的情况),建议使用成熟的CSV库如OpenCSV,它能正确处理各种CSV格式的细节。

内容的提问来源于stack exchange,提问作者Fortune Dludla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:09:03