这是我的帖子here的后续问题。
我的JTable使用abstracttablemodel
填充。我实现了一个insertRow方法,它在数据库中完美运行但不刷新我的JTable。如下面的代码所示,在插入之后,我使用fireTableRowsInserted
方法更新模型,但这似乎不起作用。带有insertRow方法的abstracttablemodel
如下:
class ResultSetTableModel extends AbstractTableModel
{
private final Connection connection;
private final Statement statement;
private ResultSet resultSet;
private ResultSetMetaData resultSetMetaData;
private int numberOfRows;
private static final String oracleDriver = "oracle.jdbc.driver.OracleDriver";
//track DB connection status
private boolean dbConnStatus = false;
//constructor initializes rSet and obtains its
//metadata object; also determines number of rows
public ResultSetTableModel(String oracleConnection, String username, String password, String query) throws SQLException
{
//connect to the database
connection = getDBConnection(oracleConnection, username, password);
//create statement to query database
statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
//update database connection status
dbConnStatus = true;
//set query and execute it
setQuery(query);
}
private static Connection getDBConnection(String oraConn, String user, String pwd)
{
Connection dbConn = null;
try
{
Class.forName(oracleDriver);
}
catch (ClassNotFoundException classExcep)
{
System.out.println(classExcep.getMessage());
}
try
{
dbConn = DriverManager.getConnection(oraConn, user, pwd);
return dbConn;
}
catch (SQLException sqlExcep)
{
System.out.println(sqlExcep.getMessage());
}
return dbConn;
}
//get class that represents column type
@SuppressWarnings({ "unchecked", "rawtypes" })
public Class getColumnClass(int column) throws IllegalStateException
{
//ensure database connection is available
if(!dbConnStatus)
throw new IllegalStateException("No connection to the Database");
//determine Java class of column
try
{
String className = resultSetMetaData.getColumnClassName(column + 1);
//return Class object that represents class Name
return Class.forName(className);
}
catch (Exception e)
{
e.printStackTrace();
}
return Object.class; //if problems occur above, assume type Object
}
//remove row in the ResultSet
public void removeRow(String empID)
{
int rsRow = 0;
try
{
//set cursor to beginning of data set (before first row)
if(!resultSet.isBeforeFirst())
resultSet.beforeFirst();
//iterate through resultSet to find matching record with
//correct employee ID. once found delete row
while(resultSet.next())
{
if(resultSet.getString("EMPLOYEENO").equals(empID))
{
rsRow = resultSet.getRow();
resultSet.absolute(rsRow);
resultSet.deleteRow();
break;
}
}
resultSet.last();
numberOfRows = resultSet.getRow();
fireTableDataChanged();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
//add row into ResultSet
public void insertRow(String fName, String lName, String userID, String company, String group)
{
//get display name of user
String displayName = fName.substring(0, 1).concat(". ").concat(lName);
try
{
//move cursor to staging row for record insertion
resultSet.moveToInsertRow();
resultSet.updateString("EMPLOYEENO", userID);
resultSet.updateString("FIRSTNAME", fName);
resultSet.updateString("LASTNAME", lName);
resultSet.updateString("DISPLAYNAME", displayName);
resultSet.updateString("GROUPNAME", group);
resultSet.updateString("COMPANYNAME", company);
resultSet.insertRow();
resultSet.beforeFirst();
//resultSet.last();
//row = resultSet.getRow();
//fireTableDataChanged();
//fireTableStructureChanged();
fireTableRowsInserted(this.getRowCount() - 1, this.getRowCount() - 1);
}
catch (SQLException e)
{
e.printStackTrace();
}
}
//get the number of columns in the ResultSet
public int getColumnCount() throws IllegalStateException
{
//ensure database connection is available
if(!dbConnStatus)
throw new IllegalStateException("No connection to the Database");
//determine number of columns
try
{
return resultSetMetaData.getColumnCount();
}
catch (SQLException sqlException)
{
sqlException.printStackTrace();
}
return 0; //if problem occur above, return 0 for number of columns
}
//get name of a particular column in ResultSet
public String getColumnName(int column) throws IllegalStateException
{
//ensure database connection is available
if(!dbConnStatus)
throw new IllegalStateException("No connection to the Database");
//determine column name
try
{
return resultSetMetaData.getColumnName(column + 1);
}
catch (SQLException sqlException)
{
sqlException.printStackTrace();
}
return ""; //if problems occur above, return empty string for column name
}
//return number of rows in ResultSet
public int getRowCount() throws IllegalStateException
{
//ensure database connection is available
if(!dbConnStatus)
throw new IllegalStateException("No connection to the Database");
return numberOfRows;
}
//obtain value in particular row and column
public Object getValueAt(int row, int column) throws IllegalStateException
{
//ensure database connection is available
if(!dbConnStatus)
throw new IllegalStateException("No connection to the Database");
//obtain a value at specified ResultSet row and column
try
{
resultSet.absolute(row + 1);
return resultSet.getObject(column + 1);
}
catch (SQLException sqlException)
{
sqlException.printStackTrace();
}
return ""; //if problems occur above, return empty string object
}
//set new database query string
public void setQuery(String query) throws SQLException, IllegalStateException
{
//ensure database connection is available
if(!dbConnStatus)
throw new IllegalStateException("No connection to the Database");
//specify query and execute it
resultSet = statement.executeQuery(query);
//obtain metadata for ResultSet
resultSetMetaData = 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();
}
//close Statement and Connection
public void disconnectFromDatabase()
{
//ensure database connection is available
if(dbConnStatus);
//determine number of columns
try
{
resultSet.close();
statement.close();
connection.close();
}
catch (SQLException sqlException)
{
sqlException.printStackTrace();
}
finally
{
dbConnStatus = false;
}
}
} //end class ResultSetTableModel

我的自定义JFrame类,包括对insert的按钮调用:
class AdministrationFrame extends JFrame
{
//set default query to retrieve all non-disabled users
private static final String DEFAULT_QUERY =
"SELECT EMPLOYEENO, FIRSTNAME, LASTNAME, DISPLAYNAME, GROUPNAME, COMPANYNAME "
+ "FROM EMPLOYEES "
+ "WHERE DISABLED IS NULL ";
//query to retrieve all groups
private static final String ALL_GROUPS_QUERY =
"SELECT DISTINCT GROUPNAME "
+ "FROM EMPLOYEES "
+ "ORDER BY GROUPNAME ";
private static final String ALL_COMPANIES_QUERY =
"SELECT DISTINCT COMPANYNAME "
+ "FROM EMPLOYEES ";
private static final String ORACLE_CONNECTION = "jdbc:oracle:thin:@..."; //connection to UAT DB
private static final String USERNAME = "...";
private static final String PASSWORD = "...";
//layout for window
private final BorderLayout layout;
private final GridBagLayout gbLayout;
private final GridBagConstraints c;
//administration window
private final JFrame adminFrame;
private final JPanel tablePanel;
private final JPanel tablePanel2;
private final JPanel modifyPanel;
private final JPanel buttonPanel;
//items for tablePanel
private final JLabel filterLabel;
private final JTextField filterTextField;
private final JButton filterButton;
//items for modifyPanel
private final JLabel firstNameLabel;
private final JLabel lastNameLabel;
private final JLabel userIDLabel;
private final JLabel companyLabel;
private final JLabel groupLabel;
private final JTextField firstNameField;
private final JTextField lastNameField;
private final JTextField userIDField;
private final JTextField companyField;
private final JTextField groupField;
private final JComboBox<String> groupsDropDown;
private final JComboBox<String> companiesDropDown;
//items for buttonPanel
private final JButton updateButton;
private Connection conn;
private JTable resultTable;
private static ResultSetTableModel tblModel;
@SuppressWarnings("unchecked")
public AdministrationFrame()
{
layout = new BorderLayout(10, 10);
setLayout(layout);
gbLayout = new GridBagLayout();
c = new GridBagConstraints();
//place GUI components on JFrame's content pane
adminFrame = new JFrame("Employee Modification Panel");
//set up JPanels
tablePanel = new JPanel();
tablePanel2 = new JPanel();
String tablePanelTitle = "Employee Details";
tablePanel.setBorder(BorderFactory.createTitledBorder(null,
tablePanelTitle, TitledBorder.CENTER, TitledBorder.TOP,
new Font("Arial", Font.BOLD + Font.ITALIC, 22), Color.BLACK));
tablePanel2.setLayout(new BoxLayout(tablePanel2, BoxLayout.Y_AXIS));
modifyPanel = new JPanel();
modifyPanel.setLayout(gbLayout);
buttonPanel = new JPanel();
//set up items in each JPanel
filterLabel = new JLabel("Filter:");
filterLabel.setAlignmentX(LEFT_ALIGNMENT);
filterTextField = new JTextField();
filterTextField.setAlignmentX(LEFT_ALIGNMENT);
filterButton = new JButton("Apply Filter");
filterButton.setAlignmentX(LEFT_ALIGNMENT);
firstNameLabel = new JLabel("First Name:");
lastNameLabel = new JLabel("Last Name:");
userIDLabel = new JLabel("Employee ID:");
companyLabel = new JLabel("Company:");
groupLabel = new JLabel("Group:");
firstNameField = new JTextField();
lastNameField = new JTextField();
userIDField = new JTextField();
companyField = new JTextField();
companyField.setEditable(false);
groupField = new JTextField();
groupField.setEditable(false);
updateButton = new JButton("Insert/Modify");
//create custom renderer for the company & group
//drop down menus - changes their behavior
class PromptComboBoxRenderer extends BasicComboBoxRenderer
{
//set the text to display when no item has been selected
private String prompt;
public PromptComboBoxRenderer(String prompt)
{
this.prompt = prompt;
}
@SuppressWarnings("rawtypes")
public Component getListCellRendererComponent(
JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus)
{
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if(value == null)
setText(prompt);
return this;
}
}
groupsDropDown = new JComboBox<String>();
groupsDropDown.setRenderer(new PromptComboBoxRenderer("Select a Group"));
groupsDropDown.addItemListener(new ItemListener() //anonymous inner class
{
@Override
public void itemStateChanged(ItemEvent event)
{
if(event.getStateChange() == ItemEvent.SELECTED)
{
if(groupsDropDown.getSelectedItem().toString() != "")
{
String selectedGroup = groupsDropDown.getSelectedItem().toString();
//System.out.println("You selected group: " + selectedGroup);
groupField.setText(selectedGroup);
}
}
}
});
companiesDropDown = new JComboBox<String>();
companiesDropDown.setRenderer(new PromptComboBoxRenderer("Select a Company"));
companiesDropDown.addItemListener(new ItemListener() //anonymous inner class
{
@Override
public void itemStateChanged(ItemEvent event)
{
if(event.getStateChange() == ItemEvent.SELECTED)
{
if(companiesDropDown.getSelectedItem().toString() != "")
{
String selectedCompany = companiesDropDown.getSelectedItem().toString();
//System.out.println("You selected company: " + selectedCompany);
companyField.setText(selectedCompany);
}
}
}
});
//user click "Insert/Modify"
updateButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
tblModel.insertRow(getFirstName(), getLastName(), getUserID(), getCompany(), getGroup());
refreshScreen();
}
});
//create ResultSetTableModel and display database table
try
{
//create TableModel for results of the default query
tblModel = new ResultSetTableModel(ORACLE_CONNECTION, USERNAME, PASSWORD, DEFAULT_QUERY);
//create JTable based on the tblModel
resultTable = new JTable(tblModel)
{
@Override
public Dimension getPreferredScrollableViewportSize()
{
return new Dimension(600, 250);
}
};
resultTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
resultTable.getTableHeader().setResizingAllowed(false); //disable column resizing
resultTable.getTableHeader().setReorderingAllowed(false); //disable column dragging
resultTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); //sets table to only allow selection of single row
resultTable.getSelectionModel().addListSelectionListener(new RowListener()); //register event handlers
final JScrollPane tablePane = new JScrollPane(resultTable);
//add items to JPanels
tablePanel2.add(filterLabel);
tablePanel2.add(Box.createRigidArea(new Dimension(0, 2)));
tablePanel2.add(filterTextField);
tablePanel2.add(Box.createRigidArea(new Dimension(0, 10)));
tablePanel2.add(filterButton);
tablePanel.add(tablePane);
tablePanel.add(tablePanel2);
buttonPanel.add(updateButton);
//fill ComboBoxes
conn = DriverManager.getConnection(ORACLE_CONNECTION, USERNAME, PASSWORD);
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet groupResultSet = stmt.executeQuery(ALL_GROUPS_QUERY);
while(groupResultSet.next())
{
String group = groupResultSet.getString("GROUPNAME");
groupsDropDown.addItem(group);
}
groupsDropDown.setSelectedIndex(-1);
groupField.setText("");
ResultSet companiesResultSet = stmt.executeQuery(ALL_COMPANIES_QUERY);
while(companiesResultSet.next())
{
String company = companiesResultSet.getString("COMPANYNAME");
companiesDropDown.addItem(company);
}
companiesDropDown.setSelectedIndex(-1);
companyField.setText("");
//add items to modifyPanel
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(10, 150, 5, 0); //no padding on right for labels
c.gridx = 0;
c.gridy = 0;
modifyPanel.add(firstNameLabel, c);
c.gridx = 0;
c.gridy = 1;
modifyPanel.add(lastNameLabel, c);
c.gridx = 0;
c.gridy = 2;
modifyPanel.add(userIDLabel, c);
c.gridx = 0;
c.gridy = 3;
modifyPanel.add(companyLabel, c);
c.gridx = 0;
c.gridy = 4;
modifyPanel.add(groupLabel, c);
c.insets = new Insets(0, 10, 5, 10); //no padding on top for fields
c.anchor = GridBagConstraints.SOUTH;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.gridx = 1;
c.gridy = 0;
c.gridwidth = 2;
modifyPanel.add(firstNameField, c);
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 2;
modifyPanel.add(lastNameField, c);
c.gridx = 1;
c.gridy = 2;
c.gridwidth = 2;
modifyPanel.add(userIDField, c);
c.gridx = 1;
c.gridy = 3;
c.gridwidth = 2;
modifyPanel.add(companyField, c);
c.gridx = 1;
c.gridy = 4;
c.gridwidth = 2;
modifyPanel.add(groupField, c);
c.insets = new Insets(0, 10, 5, 80); //padding for dropdowns
c.gridx = 4;
c.gridy = 3;
modifyPanel.add(companiesDropDown, c);
c.gridx = 4;
c.gridy = 4;
modifyPanel.add(groupsDropDown, c);
//add JPanels to frame
adminFrame.add(tablePanel, BorderLayout.NORTH);
adminFrame.add(modifyPanel, BorderLayout.CENTER);
adminFrame.add(buttonPanel, BorderLayout.SOUTH);
final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(tblModel);
resultTable.setRowSorter(sorter);
//create listener for filterButton
filterButton.addActionListener(new ActionListener()
{
//pass filter text to Listener
public void actionPerformed(ActionEvent e)
{
String text = filterTextField.getText();
if (text.length() == 0)
sorter.setRowFilter(null);
else
{
try
{
//make filter case-insensitive
sorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
}
catch (PatternSyntaxException pse)
{
JOptionPane.showMessageDialog(null, "Bad regex pattern",
"Bad regex pattern", JOptionPane.ERROR_MESSAGE);
}
}
}
});
pack();
//dispose of window when user quits application
//(do not want to close application)
adminFrame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
adminFrame.setSize(800, 600);
adminFrame.setVisible(true);
adminFrame.setLocationRelativeTo(null);
adminFrame.setResizable(false);
//ensure database is closed when user quits application
adminFrame.addWindowListener(new WindowAdapter()
{
//disconnect from database and exit when window has closed
public void windowClosed(WindowEvent event)
{
tblModel.disconnectFromDatabase();
System.exit(0);
}
});
}
catch (SQLException sqlException)
{
JOptionPane.showMessageDialog(null, sqlException.getMessage(),
"Database error", JOptionPane.ERROR_MESSAGE);
tblModel.disconnectFromDatabase();
System.exit(1); //terminate application
}
}
private class RowListener implements ListSelectionListener
{
@Override
public void valueChanged(ListSelectionEvent event)
{
if(!event.getValueIsAdjusting())
{
int row = resultTable.getSelectedRow();
if(row == -1) //no row found
JOptionPane.showMessageDialog(adminFrame, "Selected row not found in filtered set",
null, JOptionPane.WARNING_MESSAGE);
else
{
firstNameField.setText(resultTable.getValueAt(row, resultTable.getColumn("FIRSTNAME").getModelIndex()).toString());
lastNameField.setText(resultTable.getValueAt(row, resultTable.getColumn("LASTNAME").getModelIndex()).toString());
userIDField.setText(resultTable.getValueAt(row, resultTable.getColumn("EMPLOYEENO").getModelIndex()).toString());
companyField.setText(resultTable.getValueAt(row, resultTable.getColumn("COMPANYNAME").getModelIndex()).toString());
groupField.setText(resultTable.getValueAt(row, resultTable.getColumn("GROUPNAME").getModelIndex()).toString());
}
}
}
};
//refreshes the window after an update
//by clearing out all fields
//and resetting dropdown menus
public void refreshScreen()
{
firstNameField.setText("");
lastNameField.setText("");
userIDField.setText("");
companyField.setText("");
groupField.setText("");
groupsDropDown.setSelectedIndex(-1);
companiesDropDown.setSelectedIndex(-1);
}
//get methods for text fields
public String getFirstName()
{
return firstNameField.getText();
}
public String getLastName()
{
return lastNameField.getText();
}
public String getUserID()
{
return userIDField.getText();
}
public String getCompany()
{
return companyField.getText();
}
public String getGroup()
{
return groupField.getText();
}
}//end class EmpInOutBoard
&#13;
我注意到使用abstracttablemodel
的其他类似帖子使用了Lists或其他类型的集合来修改基础结果集。这也是我的应用程序所需要的东西,还是我错过了一些非常基本的东西?
提前感谢。