1

I want to display blobs from a database into a JTable column. My code is the following:

public JTable getTable(String table,String query)throws Exception{

    JTable t1 = new JTable();

    DefaultTableModel dm = new DefaultTableModel();
    Statement st = con.createStatement();
    ResultSet rs = st.executeQuery(query);
    ResultSetMetaData rsmd = rs.getMetaData();
    int cols = rsmd.getColumnCount();
    String c[] = new String[cols];
    for(int i=0;i<cols;i++){
        c[i]=rsmd.getColumnName(i+1);
        dm.addColumn(c[i]);
    }


    //get data from rows

    Object row[]=new Object[cols];
    while(rs.next()){
        row[0] = rs.getString(1);
        row[1] = rs.getString(2);
        row[2] = rs.getString(3);
        row[3] = rs.getString(4);
        row[4] = rs.getString(5);
        row[5] = rs.getString(6);
        java.sql.Blob blob = rs.getBlob(7);
        int blobLength = (int) blob.length();
        byte[] blobAsBytes = blob.getBytes(1, blobLength);
        ImageIcon picture = new ImageIcon(blobAsBytes);

        row[6] = picture;
        row[7] = rs.getString(8);
        row[8] = rs.getString(9);

        dm.addRow(row);
    }

    t1.setModel(dm);
    con.close();
    return t1;
}

When I run this code the JTable dispays: javax.swing.ImageIcon@*numbers* instead of the image itself.

TT.
  • 15,774
  • 6
  • 47
  • 88
Marko
  • 4,857
  • 5
  • 17
  • 21

2 Answers2

2

The DefaultTableModel displays any object as a String by calling its toString() method.

If you want to change that you have to tell the DefaultTableModel what the column's content is by overriding the getColumnClass() method.

   DefaultTableModel dm = new DefaultTableModel(){
     public class<?> getColumnClass(int columnIndex){
         return 6==columnIndex?ImageIcon.class, String.class;
     }
   };

But there is a chance that JTable does not have a DefaultRenderer for ImageIcon and still displays something unexpected. In that case you also have to set a DefaultRenderer for class ImageIcon yourself.

https://docs.oracle.com/javase/tutorial/uiswing/components/table.html

JTable Cell Renderer

Community
  • 1
  • 1
Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51
0

You can add a renderer that displays an icon. Such a renderer would look like this:

public class IconCellRenderer extends DefaultTableCellRenderer {
    @Override
    public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column ) {
        Component c = super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column );
        ((JLabel) c).setIcon( (ImageIcon) value );
        ((JLabel) c).setText( "" );
        return c;
    }
}

You can add this renderer several ways:

  1. Register a renderer for the ImageIcon class:

    table.setDefaultRenderer( ImageIcon.class, new IconCellRenderer( ) );
    
  2. Specify a renderer for a column:

    int imageViewIndex = table.convertColumnIndexToView( 6 ); // view index of ImageIcon data
    table.getColumnModel( ).getColumn( imageViewIndex ).setRenderer( new IconCellRenderer( ) );
    
  3. Subclass JTable and override getCellRenderer:

    final int imageModelIndex = 6; // model index of ImageIcon data
    JTable table = new JTable( ) {
        TableCellRenderer imageIconRenderer = new IconCellRenderer( );
        @Override
        public TableCellRenderer getCellRenderer( int row, int column ) {
            if( convertColumnIndexToModel( column ) == imageModelIndex )
                return imageIconRenderer;
            else
                return super.getCellRenderer( row, column );
        }
    };
    
TT.
  • 15,774
  • 6
  • 47
  • 88