簡體   English   中英

單擊JButton后如何刷新JTable

[英]How to refresh JTable after click the JButton

我有一個應用程序,該應用程序從數據庫中獲取一些數據並將其顯示在JTable 一切都OK,但是我希望單擊JButton后可以刷新我的表。 我的意思是,如果我在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) {

}
}
  1. table設為實例字段,這樣可以從actionPerformed方法訪問它
  2. 將代碼的“數據加載”部分放入另一個方法中,該方法可以從構造函數和actionPerformed方法中調用
  3. 調用actionPerformed ,調用“數據加載”方法,創建一個新的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 ,這使得管理這些類型的資源更加容易。

很好,謝謝。 但是我有一個問題,當我刷新表時,所有顯示的數據都沒有格式。 我的意思是數據不在中心,列的名稱是默認的。

重新應用格式化程序...

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事件時,表將重置渲染器

我尚未使用JTable,但解決方案應類似於以下內容。

您應該將從數據庫中獲取數據的語句移動到單獨的方法中,比如說“ getData()”。 然后,當單擊按鈕時,只需調用該方法並使用新返回的數據創建一個新的“ DefaultTableModel”對象。 然后,在JTable參考上調用方法以設置新模型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM