Integrating JDBC with Swing API for Database Interaction

Overview

This article explores how to integrate JDBC with the Swing API to create a graphical user interface for interacting with a database. It demonstrates the use of a custom TableModel implementation to display and manipulate data from a database table using a JTable. The example allows users to add rows, update the database, and discard changes using buttons in the GUI.

Implementing a Custom TableModel

To display database data in a Swing JTable, we need to implement the TableModel interface. This implementation acts as a bridge between the database and the UI component. Below is a simplified version of a CoffeesTableModel class that wraps a CachedRowSet to provide data to the table:

public class CoffeesTableModel implements TableModel {
    private CachedRowSet coffeesRowSet;
    private ResultSetMetaData metadata;
    private int numcols, numrows;

    public CoffeesTableModel(CachedRowSet rowSet) throws SQLException {
        this.coffeesRowSet = rowSet;
        this.metadata = this.coffeesRowSet.getMetaData();
        numcols = metadata.getColumnCount();

        this.coffeesRowSet.beforeFirst();
        this.numrows = 0;
        while (this.coffeesRowSet.next()) {
            this.numrows++;
        }
        this.coffeesRowSet.beforeFirst();
    }

    @Override
    public int getColumnCount() {
        return numcols;
    }

    @Override
    public int getRowCount() {
        return numrows;
    }

    @Override
    public String getColumnName(int columnIndex) {
        try {
            return metadata.getColumnLabel(columnIndex + 1);
        } catch (SQLException e) {
            return e.toString();
        }
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return String.class;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        try {
            coffeesRowSet.absolute(rowIndex + 1);
            Object o = coffeesRowSet.getObject(columnIndex + 1);
            return o == null ? null : o.toString();
        } catch (SQLException e) {
            return e.toString();
        }
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    // Other methods not shown for brevity
}

Using RowSetListener for Updates

The example also demonstrates how to listen for changes to the CachedRowSet so the UI can be refrehsed accordingly. Here’s a simplified version of the rowChanged method in the CoffeesFrame class:

public void rowChanged(RowSetEvent event) {
    try {
        coffeesRowSet.moveToCurrentRow();
        myTableModel = new CoffeesTableModel(myTableModel.getCoffeesRowSet());
        table.setModel(myTableModel);
    } catch (SQLException ex) {
        // Handle exception
    }
}

Setting Up the Swing UI

The CoffeesFrame class sets up the Swing components, including the table and buttons. Here’s a simplified version of the initialization logic:

CachedRowSet myRowSet = getContentsOfCoffeesTable();
TableModel tableModel = new CoffeesTableModel(myRowSet);
tableModel.addEventHandlersToRowSet(this);

JTable table = new JTable();
table.setModel(tableModel);

// Layout setup
Container contentPane = getContentPane();
contentPane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();

// Add buttons and text fields for user input
JButton addRowButton = new JButton("Add Row to Table");
JButton updateButton = new JButton("Update Database");
JButton discardButton = new JButton("Discard Changes");

// Add listeners to buttons (see next section)

Adding Button Lsiteners

Each button is assigned an action listener to perform specific operations on the data. Here’s a simplified version of the listener for the "Add Row" button:

addRowButton.addActionListener(e -> {
    String coffeeName = textField_COF_NAME.getText();
    int supplierId = Integer.parseInt(textField_SUP_ID.getText());
    float price = Float.parseFloat(textField_PRICE.getText());
    int sales = Integer.parseInt(textField_SALES.getText());
    int total = Integer.parseInt(textField_TOTAL.getText());

    try {
        myTableModel.insertRow(coffeeName, supplierId, price, sales, total);
    } catch (SQLException ex) {
        displaySQLExceptionDialog(ex);
    }
});

Here’s a simplified version of the listener for the "Update Database" button:

updateButton.addActionListener(e -> {
    try {
        myTableModel.coffeesRowSet.acceptChanges();
        statusLabel.setText("Database Updated");
    } catch (SQLException ex) {
        displaySQLExceptionDialog(ex);
        try {
            refreshTableModel();
            statusLabel.setText("Changes Discarded");
        } catch (SQLException ex2) {
            displaySQLExceptionDialog(ex2);
        }
    }
});

And the listener for the "Discard Changes" button:

discardButton.addActionListener(e -> {
    try {
        refreshTableModel();
    } catch (SQLException ex) {
        displaySQLExceptionDialog(ex);
    }
});

Conclusion

This article demonstrates how to integrate JDBC with the Swing API to create a dynamic, data-driven GUI application. It shows how to implement a custom TableModel, respond to data changes, and provide user interaction through buttons to manipulate database records. This approach can be adapted for other database tables and extended with more complex functionality as needed.

Tags: java JDBC swing gui TableModel

Posted on Mon, 26 Oct 2026 16:35:01 +0000 by CodeBuddy