自动更新 Jtable,从 JPanel 到 Jframe eclipse



我有数据库 JTable 来自我的 JPanel 类,我想在我的 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((,但它不起作用

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

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

更好的方法可能是简单地在构造函数中构建基本 UI,然后提供一个单独的"加载"方法,该方法从数据库中重新加载数据,可能是这样的......

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());
}
}
});
}
}

趁着我引起你的注意,让我给你介绍几个小朋友......

PreapredStatement

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());
}
}
});
}

试用资源

资源管理是一项非常重要的任务,可能很复杂。如果许多操作中的任何一个失败,则代码可能会使资源保持打开状态。 更好的解决方案是利用可用的"自动关闭"支持

你会在上面的代码中看到它,但你也可以阅读 尝试资源声明

最新更新