我正在开发一个程序(Java),它应该显示一个允许用户输入 SQL 查询的 GUI,一旦单击执行按钮,结果集应该在 GUI 上显示为表格。我可以看到空白表的初始轮廓,但是一旦执行查询,表就不会更新。我对 Java GUI 很陌生,所以我可能会犯一个非常愚蠢的错误。我想也许我只是显示一个空白的不可编辑的滚动窗格而不是实际的表格,但我不再那么确定了。老实说,我不知道我在哪里搞砸了。
我很确定清除按钮将类似于执行按钮,除了我需要创建一个空白表然后将其显示在那里。我只是无法让表格更新大声笑。无论如何,我要跑题了。我将粘贴下面的代码。下面粘贴了2个类。一个称为 QueryGUI,另一个称为 ResultTable。提前感谢您的帮助!
编辑:有什么我可以做的让这更容易帮助我吗?我已经盯着谷歌、甲骨文的网站和这个网站上的其他线程几个小时了,我不知道为什么表格不会更新/显示。
EDIT2:想通了,我试图将模型设置为我的滚动窗格而不是我的 JTable,这就是它不起作用的原因。
import java.sql.SQLException;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EtchedBorder;
public class QueryGUI extends JFrame implements ActionListener{
private static ResultTable tableModel;
private static String[] jdbcDriverStrings = {"com.mysql.jdbc.Driver", "com.ibm.db2.jdbc.netDB2Driver",
"oracle.jdbc.driver.OracleDriver", "com.jdbc.odbc.jdbcOdbcDriver"};
private static String[] dbURLStrings = {"jdbc:mysql://localhost:3306/project4", "jdbc://localhost3306/bikedb",
"jdbc:mysql://localhost3306/test"};
static String JDBC_DRIVER = null;
static String DATABASE_URL = null;
static String USERNAME = null;
static String PASSWORD = null;
static String QUERY = null;
private static JComboBox driverList = new JComboBox(jdbcDriverStrings);
private static JComboBox dbURLList = new JComboBox(dbURLStrings);
private static JTextField usernameField = new JTextField(20);
private static JPasswordField passwordField = new JPasswordField(20);
private static JTable resultTable = new JTable(tableModel); // create JTable delegate for tableModel
private static JTextArea sqlCommandEntry = new JTextArea(7, 30);
private static JScrollPane scrollingSQLCommandEntry = new JScrollPane(
sqlCommandEntry, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
private static JLabel connectionLabel = new JLabel("No Connection Now");
public static void addComponentsToPane(Container pane) {
JFrame frame = new JFrame("SQL Client GUI - (MJL)");
pane.setLayout(null);
//Create all the labels, combo boxes, buttons, and text fields/areas
JLabel comboAndTextLabel = new JLabel("Enter Database Information");
JLabel driverLabel = new JLabel("JDBC Driver");
JLabel dbURLLabel = new JLabel("Database URL");
JLabel usernameLabel = new JLabel("Username");
JLabel passwordLabel = new JLabel("Password");
JLabel SQLEntryLabel = new JLabel("Enter SQL Command");
JLabel SQLResultLabel = new JLabel("SQL Execution Result");
JButton connectButton = new JButton("Connect to Database");
JButton clearButton = new JButton("Clear Command");
JButton executeButton = new JButton("Execute SQL Command");
JButton clearResultButton = new JButton("Clear Result Window");
JScrollPane sqlResultArea = new JScrollPane(resultTable);
//scrollingSQLCommandEntry.setWrapStyleWord(true);
//scrollingSQLCommandEntry.setLineWrap(true);
pane.add(driverList);
pane.add(dbURLList);
pane.add(comboAndTextLabel);
pane.add(driverLabel);
pane.add(dbURLLabel);
pane.add(usernameLabel);
pane.add(passwordLabel);
pane.add(usernameField);
pane.add(passwordField);
pane.add(SQLEntryLabel);
pane.add(scrollingSQLCommandEntry);
pane.add(connectionLabel);
pane.add(connectButton);
pane.add(clearButton);
pane.add(executeButton);
pane.add(SQLResultLabel);
pane.add(sqlResultArea);
pane.add(clearResultButton);
//pane.add(new JScrollPane(resultTable), BorderLayout.CENTER);
driverList.addActionListener(driverList);
dbURLList.addActionListener(dbURLList);
Insets insets = pane.getInsets();
//The next giant block of code takes each component and moves them to the
//desired space on the GUI. It uses absolute positioning
//This section moves the 5 labels on the top left
Dimension size = comboAndTextLabel.getPreferredSize();
comboAndTextLabel.setBounds(8 + insets.left, 5 + insets.top,
size.width, size.height);
size = driverLabel.getPreferredSize();
driverLabel.setBounds(8 + insets.left, 26 + insets.top,
size.width, size.height);
size = dbURLLabel.getPreferredSize();
dbURLLabel.setBounds(8 + insets.left, 54 + insets.top,
size.width, size.height);
size = usernameLabel.getPreferredSize();
usernameLabel.setBounds(8 + insets.left, 80 + insets.top,
size.width, size.height);
size = passwordLabel.getPreferredSize();
passwordLabel.setBounds(8 + insets.left, 105 + insets.top,
size.width, size.height);
//This section moves the combo boxes and the text fields on the top left
size = driverList.getPreferredSize();
driverList.setBounds(90 + insets.left, 22 + insets.top,
size.width + 90, size.height);
size = dbURLList.getPreferredSize();
dbURLList.setBounds(90 + insets.left, 51 + insets.top,
size.width + 65, size.height);
size = usernameField.getPreferredSize();
usernameField.setBounds(90 + insets.left, 80 + insets.top,
size.width + 73, size.height);
size = passwordField.getPreferredSize();
passwordField.setBounds(90 + insets.left, 104 + insets.top,
size.width + 73, size.height);
//This section moves the label and text area on the top right
size = SQLEntryLabel.getPreferredSize();
SQLEntryLabel.setBounds(425 + insets.left, 5 + insets.top,
size.width, size.height);
size = scrollingSQLCommandEntry.getPreferredSize();
scrollingSQLCommandEntry.setBounds(425 + insets.left, 24 + insets.top,
size.width - 1, size.height + 4);
//Puts a border around the text area on the right
sqlCommandEntry.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
//Moves the connection status label and 3 middle buttons, also sets label color to red
size = connectionLabel.getPreferredSize();
connectionLabel.setForeground(Color.RED);
connectionLabel.setBounds(8 + insets.left, 180 + insets.top,
size.width + 175, size.height);
size = connectButton.getPreferredSize();
connectButton.setBounds(297 + insets.left, 175 + insets.top,
size.width, size.height);
size = clearButton.getPreferredSize();
clearButton.setBounds(456 + insets.left, 175 + insets.top,
size.width, size.height);
size = executeButton.getPreferredSize();
executeButton.setBounds(588 + insets.left, 175 + insets.top,
size.width, size.height);
//Moves SQL execution label and text area as well as clear result window button
size = SQLResultLabel.getPreferredSize();
SQLResultLabel.setBounds(8 + insets.left, 200 + insets.top,
size.width, size.height);
size = sqlResultArea.getPreferredSize();
sqlResultArea.setBounds(8 + insets.left, 217 + insets.top,
size.width + 295, size.height - 177);
//puts border around result text area
resultTable.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
size = clearResultButton.getPreferredSize();
clearResultButton.setBounds(20 + insets.left, 451 + insets.top,
size.width, size.height);
connectButton.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
try {
char[] tempPass = null;
USERNAME = usernameField.getText();
tempPass = passwordField.getPassword();
PASSWORD = String.valueOf(tempPass);
JDBC_DRIVER = (String)QueryGUI.driverList.getSelectedItem();
DATABASE_URL = (String)QueryGUI.dbURLList.getSelectedItem();
tableModel = new ResultTable(JDBC_DRIVER, DATABASE_URL, USERNAME, PASSWORD);
connectionLabel.setText("Connected to " + DATABASE_URL);
}
catch(ClassNotFoundException classNotFound){
JOptionPane.showMessageDialog(null,
"MySQL driver not found", "Driver not found",
JOptionPane.ERROR_MESSAGE);
System.exit(1); // terminate application
}
catch(SQLException sqlException){
JOptionPane.showMessageDialog(null, sqlException.getMessage(),
"Database error", JOptionPane.ERROR_MESSAGE);
// ensure database connection is closed
tableModel.disconnectFromDatabase();
System.exit(1); // terminate application
}
}
}
);
//create event listener for executeButton
executeButton.addActionListener(
new ActionListener(){
// pass query to table model
public void actionPerformed(ActionEvent event){
// perform a new query
try{
tableModel.setQuery(sqlCommandEntry.getText());
//These next 2 lines don't work. Bottom one line throws an eror message window
//stating can't execute query
//tableModel = new ResultTable(JDBC_DRIVER, DATABASE_URL, USERNAME, PASSWORD);
//tableModel.setUpdate(sqlCommandEntry.getText());
}
catch(SQLException sqlException){
JOptionPane.showMessageDialog(null, sqlException.getMessage(),
"Database error", JOptionPane.ERROR_MESSAGE );
}
}
}
);
}
//JDBC Driver combo box action
public void actionPerformed(ActionEvent e){
if(e.getSource() == QueryGUI.driverList){
//JComboBox cb = (JComboBox)e.getSource();
JDBC_DRIVER = (String)QueryGUI.driverList.getSelectedItem();
}
if(e.getSource() == QueryGUI.dbURLList){
DATABASE_URL = (String)QueryGUI.dbURLList.getSelectedItem();
}
}
//Create the GUI and show it.
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("SQL Client GUI - (MJL)");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the content pane.
addComponentsToPane(frame.getContentPane());
//Size and display the window.
Insets insets = frame.getInsets();
frame.setSize(785 + insets.left + insets.right,
525 + insets.top + insets.bottom);
frame.setVisible(true);
//dispose of window when user quits application (this overrides
// the default of HIDE_ON_CLOSE)
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
// ensure database connection is closed when user quits application
frame.addWindowListener(
new WindowAdapter(){
// disconnect from database and exit when window has closed
public void windowClosed(WindowEvent event){
tableModel.disconnectFromDatabase();
System.exit(0);
}
}
);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
//new QueryGUI();
createAndShowGUI();
}
});
}
}
这是二等
import java.sql.Connection;
import java.sql.Statement;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import javax.swing.table.AbstractTableModel;
public class ResultTable extends AbstractTableModel{
private Connection connection;
private Statement statement;
private ResultSet resultSet;
private ResultSetMetaData metaData;
private int numberOfRows;
// keep track of database connection status
private boolean connectedToDatabase = false;
// constructor initializes resultSet and obtains its meta data object;
// determines number of rows
public ResultTable(String driver, String url,
String username, String password)
throws SQLException, ClassNotFoundException{
// load database driver class
Class.forName(driver);
// connect to database
connection = DriverManager.getConnection(url, username, password);
// create Statement to query database
statement = connection.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
// update database connection status
connectedToDatabase = true;
// set query and execute it
//setQuery(query);
}
// get class that represents column type
public Class getColumnClass(int column) throws IllegalStateException{
// ensure database connection is available
if(!connectedToDatabase)
throw new IllegalStateException("Not Connected to Database");
// determine Java class of column
try{
String className = metaData.getColumnClassName(column + 1);
// return Class object that represents className
return Class.forName(className);
}
catch(Exception exception){
exception.printStackTrace();
}
return Object.class; // if problems occur above, assume type Object
}
// get number of columns in ResultSet
public int getColumnCount() throws IllegalStateException{
// ensure database connection is available
System.out.println("inside getColumnCount");
if(!connectedToDatabase)
throw new IllegalStateException("Not Connected to Database");
// determine number of columns
try{
return metaData.getColumnCount();
}
catch(SQLException sqlException){
sqlException.printStackTrace();
}
return 0; // if problems 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(!connectedToDatabase)
throw new IllegalStateException("Not Connected to Database");
// determine column name
try{
return metaData.getColumnName(column + 1);
}
catch(SQLException sqlException){
sqlException.printStackTrace();
}
return ""; // if problems, return empty string for column name
}
// return number of rows in ResultSet
public int getRowCount() throws IllegalStateException{
// ensure database connection is available
if(!connectedToDatabase)
throw new IllegalStateException("Not Connected to 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(!connectedToDatabase)
throw new IllegalStateException("Not Connected to Database");
// obtain a value at specified ResultSet row and column
try{
resultSet.next(); /* fixes a bug in MySQL/Java with date format */
resultSet.absolute( row + 1 );
return resultSet.getObject( column + 1 );
}
catch(SQLException sqlException){
sqlException.printStackTrace();
}
return ""; // if problems, return empty string object
}
// set new database query string
public void setQuery(String query)
throws SQLException, IllegalStateException{
// ensure database connection is available
if(!connectedToDatabase)
throw new IllegalStateException("Not Connected to Database");
// 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();
}
// set new database update-query string - this isn't working presently.
//Gives me an error message saying "Cannot issue select".
/*public void setUpdate(String query)
throws SQLException, IllegalStateException{
int res;
// ensure database connection is available
if (!connectedToDatabase)
throw new IllegalStateException("Not Connected to Database");
// specify query and execute it
res = statement.executeUpdate(query);
// notify JTable that model has changed
fireTableStructureChanged();
} */
// close Statement and Connection
public void disconnectFromDatabase(){
if (!connectedToDatabase)
return;
// close Statement and Connection
try{
statement.close();
connection.close();
}
catch(SQLException sqlException){
sqlException.printStackTrace();
}
finally{ // update database connection status
connectedToDatabase = false;
}
}
}