fireTableRowsInserted(int,int)不起作用(GUI需要重新打开)

时间:2013-09-11 18:45:03

标签: java swing jdbc jtable

public class UserPage extends JFrame implements ActionListener {

JTable table;
UserModel model;
private JButton addButton;

    public UserPage() {
    UserJDBC userJDBC = new UserJDBC();
    model = new UserModel(userJDBC.getData(), userJDBC.getColumn());
    table = new JTable(model);
    addButton = new JButton("Add User");
    addButton.addActionListener(this);
    add(addButton,BorderLayout.SOUTH);
    add(new JScrollPane(table), BorderLayout.CENTER);
    setVisible(true);
}
    @Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == addButton) addAction();
}

    public void addAction() {
    AddUserDialog UserDialog = new AddUserDialog(this);
    model.addQuery(UserDialog.getfName(), UserDialog.getlName(), UserDialog.getGender(), UserDialog.getDate());
}

AddUserDialog类:

public class AddUserDialog extends JDialog implements ActionListener {

    public AddUserDialog(JFrame owner) {
    super(owner, "New User", true);
    add(createForm(), BorderLayout.CENTER);
    setVisible(true);
    pack();
}

@Override
public void actionPerformed(ActionEvent e) {
     if (e.getSource() == okBtn) {
        okAction();
        this.dispose();
    }
}
    public void okAction() {
    setfName(fNameTf.getText());       // Get First name from text field
    setlName(lNameTf.getText());       // Get Last name from text field
    if (!genderSelection()) {          // Get gender as radio buttons
        return;
    }
    setDate(dateGenerate());          // Get date 
}

模特课程:

public class UserModel extends DefaultTableModel {

public UserModel(Vector<Vector<String>> data, Vector<String> column) {
    super(data, column);
}
    public void addQuery(String fname, String lname, String gender, String date) {
    try {
        Connection con;
        Statement statement;
        String query = "insert into UserTable(FirstName,LastName,Gender,Date) " +
                "values ( '" + fname + "' , '" + lname + "' , '" + gender + "', '" + date + "' ) ";
        con = DriverManager.getConnection(...);
        statement = con.createStatement();
        if (statement.execute(query)) {
            UserJDBC userJDBC = new UserJDBC();
            fireTableRowsInserted(userJDBC.getData().size() - 1, userJDBC.getData().size() - 1);
        }

    } catch (SQLException sqle) {
        sqle.printStackTrace();
    }
}
}

我的JDBC类:

public class UserJDBC {

Vector<String> column = new Vector<String>();
Vector<Vector<String>> data = new Vector<Vector<String>>();
Connection connection = null;
Statement statement;
ResultSet resultSet;

    public Vector<String> getColumn() {
          // get column correctly
    }

    public Vector<Vector<String>> getData() {
    try {
        connection = DriverManager.getConnection(...);
        statement = connection.createStatement();
        resultSet = statement.executeQuery("select * from Table");
        int c = resultSet.getMetaData().getColumnCount();

        while (resultSet.next()) {
            Vector<String> eachRow = new Vector<String>(c);
            for (int i = 1; i <= c; i++) {
                eachRow.add(resultSet.getString(i));
            }
            data.add(eachRow);
        }

    } catch (SQLException sqle) {
        sqle.printStackTrace();
    }
    return data;
}
}

现在,当我想添加新用户时,我的GUI需要刷新以显示新行!

更新

public void addQuery(String fname, String lname, String gender, String date) {
    try {
        Connection con;
        Statement statement;
        String query = "insert into UserTable(FirstName,LastName,Gender,Date) " +
                "values ( '" + fname + "' , '" + lname + "' , '" + gender + "', '" + date + "' ) ";
        con = DriverManager.getConnection(...);
        statement = con.createStatement();
        if (statement.execute(query)) {
            Object[] addedRow = new Object[]{fname,lname,gender,date};
            Vector addedVector = new Vector();
            addedVector.addElement(addedRow);
            this.addRow(addedRow);        // this?
            this.addRow(addedVector);     // Or this?
        }

    } catch (SQLException sqle) {
        sqle.printStackTrace();
    }
}

1 个答案:

答案 0 :(得分:4)

不要打扰,我确定太难解释你的一致性......,简单的快捷方式

1.st level,usage

private ResultSetTableModel tableModel;
private String driver = "full.name.of.driver";
private String dbName = "databseName";
private String url = "jdbc:Xxx.databaseurl, additonal parameter if needed";
private String query = "SELECT * FROM mytablename";
private JTable resultTable; 

在任何地方初始化

try {
   tableModel = new ResultSetTableModel(driver, url, query);
} catch (SQLException ex) {
   // exception handling or JOptionPane
}
resultTable = new JTable(tableModel);

和/或从void或JButtons Action

刷新TableModel
private void refreshTable(String query) {
    try {
            tableModel.setQuery(query);
    } catch (SQLException sqlException) {
            JOptionPane.showMessageDialog(null, sqlException.toString(), "SQL Exception", JOptionPane.ERROR_MESSAGE);
    }
}

AbstractTableModel上

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 javax.swing.event.TableModelEvent;
import javax.swing.table.*;
// ResultSet rows and columns are counted from 1 and JTable
// rows and columns are counted from 0. When processing
// ResultSet rows or columns for use in a JTable, it is
// necessary to add 1 to the row or column number to manipulate
// the appropriate ResultSet column (i.e., JTable column 0 is
// ResultSet column 1 and JTable row 0 is ResultSet row 1).

public class ResultSetTableModel extends AbstractTableModel {

    private static final long serialVersionUID = 1L;
    private Connection connection;
    private Statement statement;
    private ResultSet resultSet;
    private ResultSetMetaData metaData;
    private int numberOfRows;
    // initialize resultSet and obtain its meta data object determine number of rows

    public ResultSetTableModel(String driver, String url,
            String query) throws SQLException, ClassNotFoundException {
        Class.forName(driver);// load database driver class        
        connection = DriverManager.getConnection(url);// connect to database
        // create Statement to query database
        statement = connection.createStatement(
                ResultSet.TYPE_SCROLL_INSENSITIVE,
                ResultSet.CONCUR_READ_ONLY);
        setQuery(query);// set query and execute it
    }

    @Override// get class that represents column type
    public Class<?> getColumnClass(int column) {// determine Java class of column        
        try {
            String className = metaData.getColumnClassName(column + 1);
            return Class.forName(className); // return Class object that represents className
        } // catch SQLExceptions and ClassNotFoundExceptions
        catch (Exception exception) {
            exception.printStackTrace();
        }
        return Object.class;// if problems occur above, assume type Object
    }

    @Override// get number of columns in ResultSet
    public int getColumnCount() {
        try { // determine number of columns
            return metaData.getColumnCount();
        } // catch SQLExceptions and print error message
        catch (SQLException sqlException) {
            sqlException.printStackTrace();
        }
        return 0; // if problems occur above, return 0 for number of columns
    }

    @Override // get name of a particular column in ResultSet
    public String getColumnName(int column) {
        // determine column name
        try {
            return metaData.getColumnName(column + 1);
        } // catch SQLExceptions and print error message
        catch (SQLException sqlException) {
            sqlException.printStackTrace();
        }
        return "";// if problems, return empty string for column name
    }

    @Override// return number of rows in ResultSet
    public int getRowCount() {
        return numberOfRows;
    }

    @Override // obtain value in particular row and column
    public Object getValueAt(int row, int column) {
        try {  // obtain a value at specified ResultSet row and column
            resultSet.absolute(row + 1);
            return resultSet.getObject(column + 1);
        } // catch SQLExceptions and print error message
        catch (SQLException sqlException) {
            sqlException.printStackTrace();
        }
        fireTableCellUpdated(row, column);
        return "";// if problems, return empty string object
    }

    @Override // close Statement and Connection
    protected void finalize() {
        try { // close Statement and Connection
            statement.close();
            connection.close();
        } // catch SQLExceptions and print error message
        catch (SQLException sqlException) {
            sqlException.printStackTrace();
        }
    }

    // *******set new database query string*********
    public void setQuery(String query) throws SQLException {
        // specify query and execute it
        resultSet = statement.executeQuery(query);
        // obtain meta data for ResultSet
        metaData = resultSet.getMetaData();
        // determine number of rows in ResultSet
        resultSet.last();                   // move to last row
        numberOfRows = resultSet.getRow();  // get row number
        // notify JTable that model has changed
        fireTableStructureChanged();
        fireTableChanged(null);
    }

    public void tableChanged(TableModelEvent e) {
        fireTableChanged(e);
    }
}

第二。比较你的代码与这些基本的东西,例如看到连接(很长很难操作总是打开),真的这不是个好主意

注意永远不要在DefaultTableModel中调用fireWhatever,这些通知符是正确实现的,你在Swing中的Concurency是个问题