单击 JButton 后如何刷新 JTable
How to refresh JTable after click the JButton
我有一个应用程序可以从数据库中获取一些数据并将其显示在 JTable
中。一切正常,但我希望在单击 JButton
后刷新我的 table。我的意思是,如果我在 JTable 中编写 smth,在单击 JButton 之后,应用程序将再次连接到数据库,获取数据并正确显示。我试图给JButton添加一个ActionListener,但是我不知道我应该在方法actionPerformed()中写什么。
这是我的代码:
public class App extends JFrame implements ActionListener{
protected JButton button;
public App() {
Vector<Object> columnNames = new Vector<Object>();
Vector<Object> data = new Vector<Object>();
button = new JButton("Refresh");
button.addActionListener(this);
try
{
...
String query = "Select count(distinct country) sum from customers";
stmt = c.createStatement();
ResultSet rs = stmt.executeQuery(query);
query = "SELECT * from country";
rs = stmt.executeQuery(query);
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
for (int i = 1; i <= columns; i++)
{
columnNames.addElement(md.getColumnName(i));
}
while (rs.next())
{
Vector<Object> row = new Vector<Object>(columns);
for (int i = 1; i <= columns; i++)
{
row.addElement(rs.getObject(i) );
}
data.addElement(row);
}
rs.close();
stmt.close();
c.close();
}
catch(Exception e)
{
System.out.println(e);
}
DefaultTableModel model = new DefaultTableModel(data, columnNames)
{
@Override
public Class getColumnClass(int column)
{
for (int row = 0; row < getRowCount(); row++)
{
Object o = getValueAt(row, column);
if (o != null)
{
return o.getClass();
}
}
return Object.class;
}
};
JTable table = new JTable(model);
...
JScrollPane scrollPane = new JScrollPane(table);
getContentPane().add(scrollPane);
getContentPane().add(button, BorderLayout.SOUTH);
button.addActionListener(this);
}
public static void main(String[] args)
{
App frame = new App();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setSize(250,300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent arg0) {
}
}
- 使
table
成为实例字段,这样就可以从 actionPerformed
方法 访问它
- 将代码的 "data loading" 部分放入另一个方法中,该方法可以从构造函数和
actionPerformed
方法中调用
- 调用
actionPerformed
时,调用"data loading"方法,新建一个TableModel
并应用到JTable
例如
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class App extends JFrame implements ActionListener {
private static String dbName;
private static String userName;
private static String password;
protected JButton button;
private JTable table;
public App() {
button = new JButton("Refresh");
button.addActionListener(this);
table = new JTable();
try {
table.setModel(loadData());
} catch (ClassNotFoundException | SQLException | IOException ex) {
ex.printStackTrace();
}
DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment(JLabel.CENTER);
table.getColumnModel().getColumn(0).setHeaderValue("Nazwa panstwa");
table.getColumnModel().getColumn(1).setHeaderValue("Przychod netto USD");
table.getColumnModel().getColumn(0).setCellRenderer(centerRenderer);
table.getColumnModel().getColumn(1).setCellRenderer(centerRenderer);
JScrollPane scrollPane = new JScrollPane(table);
getContentPane().add(scrollPane);
getContentPane().add(button, BorderLayout.SOUTH);
button.addActionListener(this);
}
public static void main(String[] args) {
App frame = new App();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setSize(250, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
protected TableModel loadData() throws ClassNotFoundException, SQLException, IOException {
Vector<Object> columnNames = new Vector<Object>();
Vector<Object> data = new Vector<Object>();
Class.forName("org.postgresql.Driver");
try (Connection c = DriverManager.getConnection(dbName, userName, password)) {
try (BufferedReader br = new BufferedReader(new FileReader("login.txt"))) {
dbName = br.readLine();
userName = br.readLine();
password = br.readLine();
}
c.setAutoCommit(false);
System.out.println("Opened database successfully");
String query = "Select count(distinct country) sum from customers";
try (Statement stmt = c.createStatement()) {
try (ResultSet rs = stmt.executeQuery(query)) {
query = "SELECT C.country, SUM(O.netamount) "
+ "from customers as C join orders as O "
+ "on C.customerid = O.customerid "
+ "where O.orderdate < '20040701' and O.orderdate > '20031231' "
+ "group by C.country "
+ "order by SUM(O.netamount) DESC";
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
for (int i = 1; i <= columns; i++) {
columnNames.addElement(md.getColumnName(i));
}
while (rs.next()) {
Vector<Object> row = new Vector<Object>(columns);
for (int i = 1; i <= columns; i++) {
row.addElement(rs.getObject(i));
}
data.addElement(row);
}
}
}
}
return new DefaultTableModel(data, columnNames) {
@Override
public Class getColumnClass(int column) {
for (int row = 0; row < getRowCount(); row++) {
Object o = getValueAt(row, column);
if (o != null) {
return o.getClass();
}
}
return Object.class;
}
};
}
public void actionPerformed(ActionEvent arg0) {
try {
table.setModel(loadData());
} catch (ClassNotFoundException | SQLException | IOException ex) {
ex.printStackTrace();
}
}
}
您需要更好地照顾您正在创建的资源,因为 Java 7,您可以使用 try-with-resources
,这样可以更轻松地管理这些类型的资源
It's works, thank's. But I have one problem, when I refresh my table all data shown without format. I mean that data are not on the centre and name of the columns are default.
重新应用格式化程序...
public void actionPerformed(ActionEvent arg0) {
try {
table.setModel(loadData());
} catch (ClassNotFoundException | SQLException | IOException ex) {
ex.printStackTrace();
}
DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment(JLabel.CENTER);
table.getColumnModel().getColumn(0).setHeaderValue("Nazwa panstwa");
table.getColumnModel().getColumn(1).setHeaderValue("Przychod netto USD");
table.getColumnModel().getColumn(0).setCellRenderer(centerRenderer);
table.getColumnModel().getColumn(1).setCellRenderer(centerRenderer);
}
每当触发 TabelStructureChanged
事件时,table 将重置渲染器
我没有使用过 JTable,但解决方案应该类似于以下内容。
您应该将从数据库获取数据的语句移动到单独的方法中,比方说 "getData()"。然后当单击按钮时,只需调用该方法并使用新返回的数据创建一个新的 "DefaultTableModel" 对象。然后调用 JTable 引用上的方法来设置新模型。
我有一个应用程序可以从数据库中获取一些数据并将其显示在 JTable
中。一切正常,但我希望在单击 JButton
后刷新我的 table。我的意思是,如果我在 JTable 中编写 smth,在单击 JButton 之后,应用程序将再次连接到数据库,获取数据并正确显示。我试图给JButton添加一个ActionListener,但是我不知道我应该在方法actionPerformed()中写什么。
这是我的代码:
public class App extends JFrame implements ActionListener{
protected JButton button;
public App() {
Vector<Object> columnNames = new Vector<Object>();
Vector<Object> data = new Vector<Object>();
button = new JButton("Refresh");
button.addActionListener(this);
try
{
...
String query = "Select count(distinct country) sum from customers";
stmt = c.createStatement();
ResultSet rs = stmt.executeQuery(query);
query = "SELECT * from country";
rs = stmt.executeQuery(query);
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
for (int i = 1; i <= columns; i++)
{
columnNames.addElement(md.getColumnName(i));
}
while (rs.next())
{
Vector<Object> row = new Vector<Object>(columns);
for (int i = 1; i <= columns; i++)
{
row.addElement(rs.getObject(i) );
}
data.addElement(row);
}
rs.close();
stmt.close();
c.close();
}
catch(Exception e)
{
System.out.println(e);
}
DefaultTableModel model = new DefaultTableModel(data, columnNames)
{
@Override
public Class getColumnClass(int column)
{
for (int row = 0; row < getRowCount(); row++)
{
Object o = getValueAt(row, column);
if (o != null)
{
return o.getClass();
}
}
return Object.class;
}
};
JTable table = new JTable(model);
...
JScrollPane scrollPane = new JScrollPane(table);
getContentPane().add(scrollPane);
getContentPane().add(button, BorderLayout.SOUTH);
button.addActionListener(this);
}
public static void main(String[] args)
{
App frame = new App();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setSize(250,300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent arg0) {
}
}
- 使
table
成为实例字段,这样就可以从actionPerformed
方法 访问它
- 将代码的 "data loading" 部分放入另一个方法中,该方法可以从构造函数和
actionPerformed
方法中调用 - 调用
actionPerformed
时,调用"data loading"方法,新建一个TableModel
并应用到JTable
例如
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class App extends JFrame implements ActionListener {
private static String dbName;
private static String userName;
private static String password;
protected JButton button;
private JTable table;
public App() {
button = new JButton("Refresh");
button.addActionListener(this);
table = new JTable();
try {
table.setModel(loadData());
} catch (ClassNotFoundException | SQLException | IOException ex) {
ex.printStackTrace();
}
DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment(JLabel.CENTER);
table.getColumnModel().getColumn(0).setHeaderValue("Nazwa panstwa");
table.getColumnModel().getColumn(1).setHeaderValue("Przychod netto USD");
table.getColumnModel().getColumn(0).setCellRenderer(centerRenderer);
table.getColumnModel().getColumn(1).setCellRenderer(centerRenderer);
JScrollPane scrollPane = new JScrollPane(table);
getContentPane().add(scrollPane);
getContentPane().add(button, BorderLayout.SOUTH);
button.addActionListener(this);
}
public static void main(String[] args) {
App frame = new App();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setSize(250, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
protected TableModel loadData() throws ClassNotFoundException, SQLException, IOException {
Vector<Object> columnNames = new Vector<Object>();
Vector<Object> data = new Vector<Object>();
Class.forName("org.postgresql.Driver");
try (Connection c = DriverManager.getConnection(dbName, userName, password)) {
try (BufferedReader br = new BufferedReader(new FileReader("login.txt"))) {
dbName = br.readLine();
userName = br.readLine();
password = br.readLine();
}
c.setAutoCommit(false);
System.out.println("Opened database successfully");
String query = "Select count(distinct country) sum from customers";
try (Statement stmt = c.createStatement()) {
try (ResultSet rs = stmt.executeQuery(query)) {
query = "SELECT C.country, SUM(O.netamount) "
+ "from customers as C join orders as O "
+ "on C.customerid = O.customerid "
+ "where O.orderdate < '20040701' and O.orderdate > '20031231' "
+ "group by C.country "
+ "order by SUM(O.netamount) DESC";
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
for (int i = 1; i <= columns; i++) {
columnNames.addElement(md.getColumnName(i));
}
while (rs.next()) {
Vector<Object> row = new Vector<Object>(columns);
for (int i = 1; i <= columns; i++) {
row.addElement(rs.getObject(i));
}
data.addElement(row);
}
}
}
}
return new DefaultTableModel(data, columnNames) {
@Override
public Class getColumnClass(int column) {
for (int row = 0; row < getRowCount(); row++) {
Object o = getValueAt(row, column);
if (o != null) {
return o.getClass();
}
}
return Object.class;
}
};
}
public void actionPerformed(ActionEvent arg0) {
try {
table.setModel(loadData());
} catch (ClassNotFoundException | SQLException | IOException ex) {
ex.printStackTrace();
}
}
}
您需要更好地照顾您正在创建的资源,因为 Java 7,您可以使用 try-with-resources
,这样可以更轻松地管理这些类型的资源
It's works, thank's. But I have one problem, when I refresh my table all data shown without format. I mean that data are not on the centre and name of the columns are default.
重新应用格式化程序...
public void actionPerformed(ActionEvent arg0) {
try {
table.setModel(loadData());
} catch (ClassNotFoundException | SQLException | IOException ex) {
ex.printStackTrace();
}
DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment(JLabel.CENTER);
table.getColumnModel().getColumn(0).setHeaderValue("Nazwa panstwa");
table.getColumnModel().getColumn(1).setHeaderValue("Przychod netto USD");
table.getColumnModel().getColumn(0).setCellRenderer(centerRenderer);
table.getColumnModel().getColumn(1).setCellRenderer(centerRenderer);
}
每当触发 TabelStructureChanged
事件时,table 将重置渲染器
我没有使用过 JTable,但解决方案应该类似于以下内容。
您应该将从数据库获取数据的语句移动到单独的方法中,比方说 "getData()"。然后当单击按钮时,只需调用该方法并使用新返回的数据创建一个新的 "DefaultTableModel" 对象。然后调用 JTable 引用上的方法来设置新模型。