如何在点击按钮时刷新继承AbstractTableModel的自定义JTable模型以显示新值?
看起来你遇到的问题很典型——模型数据已经更新了(从控制台打印能看出来),但界面上的JTable就是没反应。我帮你梳理下代码里的几个关键问题,以及对应的修复方案:
核心问题1:重复创建JTable却没关联到界面
在升序按钮的事件处理里,你写了spreadSheet = new JTable(new MyModel());,然后又spreadSheet.setModel(NewModel);。但这个新创建的spreadSheet根本没有添加到你的UI容器里,界面上显示的还是原来的那个JTable实例,所以不管你怎么更新新模型的数据,旧的表格根本感知不到。
修复方案:
直接复用你一开始就添加到界面上的那个JTable实例,彻底删掉spreadSheet = new JTable(new MyModel());这一行。同时确保NewModel是你初始化界面时就绑定给JTable的那个模型实例(比如在UI初始化的时候就创建NewModel = new MyModel();,然后spreadSheet = new JTable(NewModel);)。
核心问题2:数据集合没有清空,每次点击都追加旧数据
不管是升序还是降序按钮,你处理数据时都是直接往Rs集合里add新行,但从来没有清空过它。这会导致每次点击按钮,旧的数据还留在集合里,新数据又被追加进去,最终模型里的数据是新旧混合的,显示自然不对。
修复方案:
在循环拆分字符串添加行之前,先清空Rs集合:
// 清空旧数据,准备加载新数据 Rs.clear(); for (String g : strings) { OneRow = g.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"); Rs.add(OneRow); }
核心问题3:TableModel的setValueAt方法存在空指针隐患
你的MyModel里重写了setValueAt方法,但里面的cells数组是null的,直接调用cells[rowIndex][columnIndex]会抛出空指针异常。虽然你的表格设置为不可编辑,但这个方法的错误实现可能会影响模型的稳定性。
修复方案:
因为你的表格是不可编辑的,要么直接删掉这个重写的方法(AbstractTableModel的默认实现本来就不会做任何操作),要么修改成正确的逻辑(如果以后要支持编辑的话):
@Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { // 如果不需要编辑,这里可以留空 // 如果以后要支持编辑,改成操作Data集合: // Data.get(rowIndex)[columnIndex] = (String) aValue; // fireTableCellUpdated(rowIndex, columnIndex); }
修改后的按钮事件示例(以升序按钮为例)
ascendingButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { MyProgramUtility hehe = new MyProgramUtility(); String path = "src\\res\\data.csv"; try { ArrayList<Citizen> array = MyProgramUtility.printNameAscending(MyProgramUtility.readCSV(path), path); List<String> strings = array.stream() .map(object -> Objects.toString(object, null)) .collect(Collectors.toList()); // 关键:清空旧数据 Rs.clear(); for (String g : strings) { OneRow = g.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"); Rs.add(OneRow); } // 直接用已绑定的模型更新数据,触发界面刷新 NewModel.AddCSVData(Rs); System.out.println("Rows: " + NewModel.getRowCount()); System.out.println("Cols: " + NewModel.getColumnCount()); } catch (FileNotFoundException fileNotFoundException) { fileNotFoundException.printStackTrace(); } } });
把降序按钮的事件也做同样的修改(加上Rs.clear();),然后再运行试试,应该就能看到JTable正常刷新新数据了。
内容的提问来源于stack exchange,提问作者user15082428

