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

DefaultTableModel更新异常:点击JTable旧数据复现如何解决?

问题分析与解决方案

你的问题根源在于每次点击Search按钮时,都会创建新的JTable和JScrollPane并添加到面板中,导致多个表格组件叠加在一起。表面上看新数据显示在最上层,但点击时可能触发了底层旧表格的事件,从而显示旧模型的数据。

修复步骤

1. 将表格相关组件改为类成员变量

把JTable、JScrollPane和DefaultTableModel提升为类的成员,确保整个生命周期内只创建一次。

2. 在构造方法中初始化表格组件

在构造方法里完成表格、滚动面板的创建和布局添加,而不是每次搜索时重复添加。

3. 修改showTable方法,仅更新模型数据

不再新建组件,而是清空现有模型的行数据,重新查询数据库并填充新数据。

修改后的完整代码

import javax.swing.*;
import javax.swing.GroupLayout.Alignment;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.*;

public class store extends JPanel{
    
    int WIDTH = 1000;
    int HEIGHT = 600;
    String[] columnnames = new String[] {"id", "type", "cost"};
    JComboBox jcb;
    JButton button;
    // 改为类成员变量
    DefaultTableModel dtm;
    JTable t;
    JScrollPane pane;
    
    public store() {
        super();
        this.setVisible(true);
        this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
        this.setBackground(new Color(224, 224, 224));
        
        GroupLayout gLayout = new GroupLayout(this);
        gLayout.setAutoCreateGaps(true);
        gLayout.setAutoCreateContainerGaps(true);
        this.setLayout(gLayout);
        
        this.jcb = new JComboBox();
        
        this.button=new JButton("Search");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                showTable();
            }
        });
        
        // 初始化表格组件
        dtm = new DefaultTableModel(columnnames, 0);
        t = new JTable(dtm);
        pane = new JScrollPane(t);
        pane.setPreferredSize(new Dimension(850, 150));
        
        // 加载下拉框数据
        try { 
            Class.forName("org.postgresql.Driver");
            try(Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/Try", "postgres", "******")) {
                String sql = "select distinct type from try";
                try(PreparedStatement ps = conn.prepareStatement(sql);
                    ResultSet rs2 = ps.executeQuery()) {
                    while (rs2.next()) {
                        String aS = rs2.getString(1);
                        jcb.addItem(aS);
                    }
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        
        // 调整布局,添加表格滚动面板
        gLayout.setHorizontalGroup(gLayout.createSequentialGroup()
                .addGap(400)
                .addComponent(jcb)
                .addComponent(button)
                .addGap(400)
        );
        gLayout.setVerticalGroup(gLayout.createSequentialGroup()
                .addGap(50)
                .addGroup(gLayout.createParallelGroup(Alignment.CENTER)
                        .addComponent(jcb)
                        .addComponent(button)
                )
                .addGap(20)
                .addComponent(pane)
                .addGap(250)
        );
    }
    
    public void showTable() {
        // 清空现有模型数据
        dtm.setRowCount(0);
        
        String ta = jcb.getSelectedItem().toString();

        try { 
            Class.forName("org.postgresql.Driver");
            // 使用try-with-resources自动关闭连接、语句、结果集
            try(Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/Try",
                    "postgres", "*****");
                PreparedStatement pstm = conn.prepareStatement(
                        "SELECT try.* FROM try WHERE type=?")) {
                pstm.setString(1, ta);
                try(ResultSet Rs = pstm.executeQuery()) {
                    while (Rs.next()) {
                        dtm.addRow(new Object[] { Rs.getString(1), Rs.getString(2), Rs.getString(3) });
                    }
                }
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }
}

关键修改说明

  • 组件复用:表格和滚动面板只初始化一次,避免多次添加导致的组件叠加问题。
  • 模型更新:通过dtm.setRowCount(0)清空旧数据,再添加新行,确保模型始终是当前最新数据。
  • 资源管理:使用try-with-resources语法自动关闭数据库连接、PreparedStatement和ResultSet,避免资源泄漏。
  • 布局优化:将表格滚动面板加入GroupLayout,替代原来的setBounds硬编码位置,适配布局管理器的规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 18:01:20