I have an application which get some data from database and show it in the JTable
. Everything is OK, but I want that my table will be refreshed after clicking JButton
. I mean that if I write smth in JTable, after clicking JButton, application will again connect with database, get the data and show it correctly. I tried to add an ActionListener to the JButton, but I don't know what I should write in the method actionPerformed().
Here is my code:
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
an instance field, this way it can be accessed from the actionPerformed
method actionPerformed
method actionPerformed
is called, call the "data loading" method, create a new TableModel
and apply it to the JTable
For example
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();
}
}
}
You need to take better care of the resources you are creating, since Java 7, you can use try-with-resources
which makes it easier to manage these types of 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.
The reapply the formatters...
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);
}
When ever the TabelStructureChanged
event is triggered, the table will reset the renderers
I haven't worked with JTable but the solution should be similar to the following.
You should move the statements that get data from the database to a separate method, let's say "getData()". Then when the button is clicked, simply call the method and create a new "DefaultTableModel" object with the newly returned data. Then call the method on your JTable reference to set the new model.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.