1

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

2
  • Shouldn't you be reading the contents of the blob column? Maybe through ImageIO? Commented Aug 22, 2014 at 1:44
  • @peeskillet that didnt work for me...i am using a vector for my rows while he used an Object array...i was able to do the override but didnt know how to add the icon to my newRow vector... Commented Aug 22, 2014 at 3:05

1 Answer 1

3

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"));

Sign up to request clarification or add additional context in comments.

10 Comments

thanks for your quick reply and your time. but i am getting a java.sql.SQLException: not implemented by SQLite JDBC driver against blob blob = rs.getBlob("image") any hints? thanks again bro...
How exactly do you save the image? I'm not familiar with SQLlite. Are you saving it as a blob? Also you said you have been able to retrieve the images before. Why don't you explain how you did that.
You need to make sure that that you return ImageIcon.class for the correct column. Remember the indices are 0 based, meaning they start at 0. Check that you aren't one off.
Looking at your query, image is the 9th, meaning in the table, the index should be 8 ;-)
@peeskillet...it worked!!!!!!!!!! :) i changed the index to 8! ... thanks bro!!! Jeez! you have really relieved me of stress! thanks again...i owe you one :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.