当前位置: 首页 > 知识库问答 >
问题:

自动更新Jtable从JPanel到Jframe eclipse

章增
2023-03-14

我的JPanel类中有数据库JTable,我想在我的JFRame类中使用它

我希望通过单击一些按钮来自动更新JTable
这并不是错误,但它不希望自动更新,除非我将Jframe放在Jpanel类上,这将生成一个新的帧

这是我的JPanel

 public class TUsers extends JPanel {

    private static final long serialVersionUID = 1L;  

    String [] header = {"Id","name","address"};
    JTable BTab = new JTable(); 
    JScrollPane scrPnl = new JScrollPane();
    public Object [][] table = null;

     TUsers(){
        Dbcon dc = new Dbcon();
        Connection psql = dc.getConnection();
        try 
        {
            Statement stmt = psql.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
            String sql = "SELECT * FROM public.patrons ORDER BY id ASC";
            ResultSet res = stmt.executeQuery(sql);
            ResultSetMetaData meta = res.getMetaData();
            int y  = meta.getColumnCount();
            int x = 0;
            while(res.next())
            {
                y = res.getRow();
            }
            table = new Object[x][y];
            int n = 0;
            res.beforeFirst();
            while(res.next())
            {
                table[n][0]=res.getString("Id");
                table[n][1]=res.getString("name");
                table[n][2]=res.getString("address");
                x++;
            }
            scrPnl.setViewportView(BTab);
            BTab.setModel(new DefaultTableModel(table, header));
            TableColumnModel table = BTab.getColumnModel();

            table.getColumn(0).setPreferredWidth(2);
            table.getColumn(1).setPreferredWidth(100);
            table.getColumn(2).setPreferredWidth(180);

            scrPnl.setPreferredSize(new Dimension(350, 120));

            add(scrPnl, BorderLayout.CENTER);
            revalidate();
            repaint();
            stmt.close();
            res.close();

这是我的JFrame类中的内容

  public class AddUser extends JFrame {
    TUsers t = new TUsers();


AddUser()
{
    setTitle("Admin");
    setLocation(400,400);
    setSize(400, 400);
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

}

    void Layout()
  {
   getContentPane().add(t).setBounds(10, 225, 350, 150);
   //if i delete this it wont show the table

    setVisible(true);
  } 



    void EventHandle() 
   {
  b_crt.addActionListener(new ActionListener() 
    {
        public void actionPerformed(ActionEvent e)
        {
            Dbcon dc = new Dbcon();
            Connection psql = dc.getConnection();
            try
            {
                Statement stmt = psql.createStatement();
                String sql = "INSERT INTO public.patrons VALUES ('"
                            +t_id.getText()+"','"
                            +t_usrnm.getText()+"','"
                            +t_adrs.getText()+"');";
                int i = stmt.executeUpdate(sql);
                if(i == i) 
                {
                    JOptionPane.showMessageDialog(null, "Success");
                }
                Clear();
            }
            catch(Exception x)
            {
                JOptionPane.showMessageDialog(null, x.getMessage());
            }

            TUsers t = new TUsers();

         }
        });
   }
}   

我已经在JPanel上放置了
repaint()和revalidate(),但它不起作用

共有1个答案

傅彬
2023-03-14

好的,让我们后退一步,重新考虑一下tusers类。

当前的实现有一个副作用,就是作为类初始化阶段的一部分加载数据库信息。这有几个问题,主要问题是如果不创建一个新实例,就无法更新表。

更好的方法可能是简单地在构造函数中构建基本UI,然后提供一个单独的“Load”方法来从数据库中重新加载数据,可能类似于...

public class TUsers extends JPanel {

    private static final long serialVersionUID = 1L;

    String[] header = {"Id", "name", "address"};
    JTable BTab = new JTable();
    JScrollPane scrPnl = new JScrollPane();

    TUsers() {
        // Build the UI
        setLayout(new BorderLayout());
        DefaultTableModel model = new DefaultTableModel(header, 0);
        BTab = new JTable(model);
        scrPnl.setViewportView(BTab);
        add(scrPnl);
    }

    public void loadData() throws SQLException {
        Dbcon dc = new Dbcon();
        String sql = "SELECT * FROM public.patrons ORDER BY id ASC";
        try (Connection psql = dc.getConnection();
                Statement stmt = psql.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
                ResultSet res = stmt.executeQuery(sql)) {
            DefaultTableModel model = new DefaultTableModel(header, 0);
            while (res.next()) {
                String[] rowData = new String[3];
                rowData[0] = res.getString("Id");
                rowData[1] = res.getString("name");
                rowData[2] = res.getString("address");
                model.addRow(rowData);
            }
            BTab.setModel(model);
            BTab.getColumn(0).setPreferredWidth(2);
            BTab.getColumn(1).setPreferredWidth(100);
            BTab.getColumn(2).setPreferredWidth(180);
        }
    }
}

只需确保在某个时刻调用loaddata,否则它将显示一个空表。

现在,如果需要,可以调用loaddata并刷新表...

public class AddUser extends JFrame {

    TUsers t = new TUsers();

    AddUser() {
        setTitle("Admin");
        setLocation(400, 400);
        setSize(400, 400);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        // When does t get added??
    }

    void Layout() {
        getContentPane().add(t).setBounds(10, 225, 350, 150);
        //if i delete this it wont show the table
        // This is a symptom of a different problem
        setVisible(true);
    }

    void EventHandle() {
        b_crt.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Dbcon dc = new Dbcon();
                String sql = "INSERT INTO public.patrons VALUES ('"
                        + t_id.getText() + "','"
                        + t_usrnm.getText() + "','"
                        + t_adrs.getText() + "');";
                try (Connection psql = dc.getConnection();
                        Statement stmt = psql.createStatement()) {
                    int i = stmt.executeUpdate(sql);
                    if (i == i) {
                        JOptionPane.showMessageDialog(null, "Success");
                    }
                    t.loadData();
                } catch (Exception x) {
                    JOptionPane.showMessageDialog(null, x.getMessage());
                }

            }
        });
    }
}

趁你注意,我给你介绍几个小朋友...

PreparedStatement保护您免受可能的SQL注入问题的影响,并支持多种不同的数据类型,从而使您不必为不同的数据库尝试如何转换它们

有关详细信息,请参阅如何使用PreparedStatement

void EventHandle() {
    b_crt.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Dbcon dc = new Dbcon();
            String sql = "INSERT INTO public.patrons VALUES (?, ?, ?)";
            try (Connection psql = dc.getConnection();
                    PreparedStatement stmt = psql.prepareStatement(sql)) {
                stmt.setString(1, t_id.getText());
                stmt.setString(2, t_usrnm.getText());
                stmt.setString(3, t_adrs.getText());
                int i = stmt.executeUpdate(sql);
                if (i == i) {
                    JOptionPane.showMessageDialog(null, "Success");
                }
                t.loadData();
            } catch (Exception x) {
                JOptionPane.showMessageDialog(null, x.getMessage());
            }

        }
    });
}

资源管理是一项非常重要的任务,也是一项复杂的任务。如果许多操作中的任何一个失败,您的代码就会冒着资源未打开的风险。更好的解决方案是利用可用的“自动关闭”支持

您将在上面的代码中看到它,但是您也可以阅读try-with-resources语句

 类似资料:
  • 我找到了更新数据的示例,但它使用了DefaultTableModel。当我创建自己的TableModel和自己的data类时,当我将数据添加到JTable中时,它不会更新。 有我的桌子模型: 当我添加了任何信息,但它没有更新。在JTable中,我必须把这个方法放在哪里来进行正确的数据更新?

  • autoUpdater模块为Squirrel框架提供了一个接口。 进程: 主进程​ 您可以使用这些项目之一进行快速启动多平台发布服务器以分发应用程序: nuts:为您的应用程序使用智能版本服务器,使用GitHub作为后端。使用Squirrel(Mac和Windows)自动更新 electron-release-server:功能齐全,自主托管的electron应用程序的发布服务器,兼容自动更新器

  • 我已经在这个问题上搜索了几个小时,但似乎没有任何效果。 我有一个JTable,框架内有一个JPanel。该表包含来自数据库的数据,但要存储大量数据(因此需要JScrollPane) 下面是我的代码: 我的代码可能不是很好,因为我已经遵循了几个关于如何克服这个问题的教程,并将它们混合在一起。 任何帮助都很感激! 编辑:

  • 我一直在试图找到一种通过直接输入来更新我的细胞的方法。从我的研究来看,每个人似乎都说你必须使用 尽管如此,它还是让我投myJTable-- 以下是我当前的表代码,如果这有帮助的话: 我怎么可能从用户直接输入更新的单元格中保存数据?谢谢!

  • 我现在迷路了。