spynoble
spynoble

Reputation: 33

how to display a database table with blobs in a JTable

i am trying to display a database table with blobs on a Jtable and i want the images to show but instead i get a set of codes in the column for images...Here are my codes:

this class retrieves my db table from database through a result set...

public class rs2Table {

public static TableModel resultSetToTableModel(ResultSet rs) {
    try {
        ResultSetMetaData metaData = rs.getMetaData();
        int numberOfColumns = metaData.getColumnCount();
        Vector<String> columnNames = new Vector<String>();

        // Get the column names
        for (int column = 0; column < numberOfColumns; column++) {
            columnNames.addElement(metaData.getColumnLabel(column + 1));
        }

        // Get all rows.
        Vector<Vector<Object>> rows = new Vector<Vector<Object>>();

        while (rs.next()) {
            Vector<Object> newRow = new Vector<Object>();

            for (int i = 1; i <= numberOfColumns; i++) {
                newRow.addElement(rs.getObject(i));
            }

            rows.addElement(newRow);
        }

        return new DefaultTableModel(rows, columnNames) {
            @Override
            public boolean isCellEditable(int row, int column) {
                //return all cells false
                return false;
            }
        };
    } catch (SQLException e) {
        JOptionPane.showMessageDialog(null,e);
        return null;
    }
}

this is where i try to display the database table with images and other fields...

private void retrvStaffList() {
    try {
        //this sql uses LEFT JOIN to merge tables with corresponding foreign keys
        //hence we it is going to display all staff with their specified info retrieved      from all the tables in ONE table...
        String sql = "SELECT DISTINCT s.StaffName, d.DeptName, b.age, b.telephone, b.email, b.address, t.position, t.salary, b.image FROM Staffs AS s\n"
                + "LEFT JOIN  Departments as d ON d.DepartmentID = s.DepartmentID\n"
                + "LEFT JOIN BioData AS b ON b.BioID = s.StaffID\n"
                + "LEFT JOIN StatusTable AS t ON t.ownerID = s.StaffID\n"
                + "ORDER BY s.StaffName";
        PreparedStatement pStmt2 = connect.prepareStatement(sql);
        rs = pStmt2.executeQuery();

                //get the staff table...
                staffTable.setModel(rs2Table.resultSetToTableModel(rs));

    } catch (SQLException ex) {
        Logger.getLogger(StaffList.class.getName()).log(Level.SEVERE, null, ex);
    }
}

i have retrieved the images for other purposes successfully but i dont know how i will go about inserting it in a JTable alongside other fields. i know i might have to use a byte to get the images and then pass it to an image icon like i did other times i retrieved the images for other purposes, but i dont know which of the methods to apply that.

please guys any hint is highly appreciated...thanks in advance

Upvotes: 1

Views: 3708

Answers (1)

Paul Samsotha
Paul Samsotha

Reputation: 209002

The goal is the get the image from the db into an ImageIcon so that you can take advantage of the default renderer, without having to provide your own renderer implementation (See How to use Tables: Editors and Renderers).

Since you haven't provided how you "have retrieved the images for other purposes successfully", I'll provide my own:

while (rs.next()) {
    Vector<Object> newRow = new Vector<Object>();

    for (int i = 1; i <= numberOfColumns; i++) {
        if (i == <imageColumn>) {  // ... whatever column is your image column
            Blob blob = rs.getBlob("image");
            int blobLength = (int) blob.length();  

            byte[] bytes = blob.getBytes(1, blobLength);
            blob.free();
            BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));
            ImageIcon icon = new ImageIcon(img);  
            newRow.addElement(icon);  
        } else {
            newRow.addElement(rs.getObject(i));
        }
    }
    rows.addElement(newRow);
}

Then it's just a matter of overriding getColumnClass() on your DefaultTableModel (so the default renderer can render it as an ImageIcon), as explained in this answer.

You probably want to resize the row/column accordingly too, to fit the image. You can do that simply by doing something like

table.setRowHeight(height);
TableColumn column = table.getColumn("ColumnIdentifier");
column.setWidth(width);

Javadoc Resources:


EDIT

With SQLlite it seems you should read as rs.getBytes("image");. Also after further reading the docs, you could also simple construct the ImageIcon with the byte[] returned. new ImageIcon(rs.getBytes("image"));

Upvotes: 3

Related Questions