1

I have changed the cell render in JTable to show image instead of text using the following code:

base_table.getColumnModel().getColumn(3).setCellRenderer(new TableCellRenderer() {

    @Override
    public Component getTableCellRendererComponent(JTable jtable, Object value,
            boolean bln, boolean bln1, int i, int i1) {
        JLabel lbl = new JLabel();
        lbl.setIcon((ImageIcon) value);
        return lbl;
    }
});

Now, I'd like to be able to get the image for each row in the JTable in order to save it in database. How could I do that?

Jonas
  • 121,568
  • 97
  • 310
  • 388
Feras Odeh
  • 9,136
  • 20
  • 77
  • 121
  • 2
    Are the images are already in your data model? – trashgod Aug 13 '11 at 09:16
  • 3
    unrelated to your problem: dont create a new comp on each call, instead do it once and configure in later calls – kleopatra Aug 13 '11 at 09:59
  • @trashgod, ya I think some of the image he had it there, while some others not. SO anyway, how to set the Image on each cells IF at first we already have its Cells containing JLabel? – gumuruh Aug 23 '11 at 00:18
  • @mKorbel's example shows how to get the [default renderer](http://download.oracle.com/javase/tutorial/uiswing/components/table.html#editrender) for `Icon`, but you may want to keep references to the images in your model; `List` would make sense. – trashgod Aug 23 '11 at 00:40

4 Answers4

4

I can't resist just example for that

enter image description here enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.*;
import javax.swing.table.*;

public class TableIcon extends JFrame implements Runnable {

    private static final long serialVersionUID = 1L;
    private JTable table;
    private JLabel myLabel = new JLabel("waiting");
    private int pHeight = 40;
    private boolean runProcess = true;
    private int count = 0;

    public TableIcon() {
        ImageIcon errorIcon = (ImageIcon) UIManager.getIcon("OptionPane.errorIcon");
        ImageIcon infoIcon = (ImageIcon) UIManager.getIcon("OptionPane.informationIcon");
        ImageIcon warnIcon = (ImageIcon) UIManager.getIcon("OptionPane.warningIcon");
        String[] columnNames = {"Picture", "Description"};
        Object[][] data = {{errorIcon, "About"}, {infoIcon, "Add"}, {warnIcon, "Copy"},};
        DefaultTableModel model = new DefaultTableModel(data, columnNames) {

            private static final long serialVersionUID = 1L;
            //  Returning the Class of each column will allow different
            //  renderers to be used based on Class

            @Override
            public Class getColumnClass(int column) {
                return getValueAt(0, column).getClass();
            }
        };
        table = new JTable(model);
        table.setRowHeight(pHeight);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane, BorderLayout.CENTER);
        myLabel.setPreferredSize(new Dimension(200, pHeight));
        myLabel.setHorizontalAlignment(SwingConstants.CENTER);
        add(myLabel, BorderLayout.SOUTH);
        new Thread(this).start();
    }

    public void run() {
        while (runProcess) {
            try {
                Thread.sleep(1250);
            } catch (Exception e) {
                e.printStackTrace();
            }
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    ImageIcon myIcon = (ImageIcon) table.getModel().getValueAt(count, 0);
                    String lbl = "JTable Row at :  " + count;
                    myLabel.setIcon(myIcon);
                    myLabel.setText(lbl);
                    count++;
                    if (count > 2) {
                        count = 0;
                    }
                }
            });
        }
    }

    public static void main(String[] args) {
        TableIcon frame = new TableIcon();
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setLocation(150, 150);
        frame.pack();
        frame.setVisible(true);
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • -1 for overriding the table's getColumnClass - that's definitely the responsibility of the _model_ (how could I have missed this last summer :-) – kleopatra Feb 08 '12 at 11:25
  • @kleopatra last summer was really very strange, :-) – mKorbel Feb 08 '12 at 11:27
  • insistive me: the view must not second-guess the model's intentions (what if the model intentionally returned the widest possible type because it allows and in fact contains a variety of icons, strings, numbers...)? While this is an example only - which we would never code in in any real-world environment - the mis-placement is spreading, see f.i http://stackoverflow.com/questions/9239270/how-to-change-jtable-image-from-one-column-to-another-column-using-mouse-click-e – kleopatra Feb 11 '12 at 11:12
  • See also this (recently updated) [answer](http://stackoverflow.com/a/9155689/230513). – trashgod Feb 11 '12 at 12:09
3

The data stored in a JTable can be found in its TableModel. But since it's your code, normally, that builds this TableModel (from a list or an array, typically), you should be able to get the icon from this list or array. Else, just use table.getModel().getValueAt(row, column), and cast it to an ImageIcon.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • @mKorbel: thanks for the edit, but a vector IS a list, and there's no need to override getColumnClass to put an ImageIcon in a table model (especially since the OP has a specific renderer for this column). Please suggest an edit next time rather than doing it for me. – JB Nizet Aug 13 '11 at 09:39
  • I get a String from table.getModel().getValueAt(row, column) – Feras Odeh Aug 13 '11 at 09:41
  • 2
    Then your renderer code is incorrect, because it casts the value in the cell to an ImageIcon. You should know what your model contains. How do you build the table model? – JB Nizet Aug 13 '11 at 09:53
  • @JB Nizet that for getColumnClass there exist :-), just Column.class can do that only once time and correctly, Renderer is for modifying something in the TableCell, not for create ..., simply doing nothing, wrong as (@kleopatra) notified, please read http://stackoverflow.com/questions/5614875/how-to-set-icon-in-a-column-of-jtable, nothing better around, – mKorbel Aug 13 '11 at 13:37
  • @mKorbel: getColumnClass is used to let the JTable know which kind of renderer it must set on the column cells. If you set a renderer explicitely, as the OP did, there is no need for getColumnClass. – JB Nizet Aug 13 '11 at 13:57
  • @JB Nizet please see my post, there are lots of ways, just against reinvent the wheel and complicated simple things too, nor please not as attack to your kind person – mKorbel Aug 13 '11 at 14:29
  • @JB Nizet, The DefaultTableMOdel does not support a List, so Vector is more approriate in the context of this question. If the poster understood how to create a custom TableModel then yes they could use a List, but given they have a question about the getValueAt() method I doubt they have the knowledge to create a custom model. – camickr Aug 13 '11 at 15:06
  • @camickr: a Vector **is** a List. So, when I say that a table model is typically built from a List, it's true, whether DefaultTableModel is used or not. Adding "or from a Vector" doesn't make it more true. – JB Nizet Aug 13 '11 at 15:10
  • Also, we are here to promote common practices. Overriding getColumnClass() is the standard way to do this for two reasons. Frist you don't need to create a custom renderer. Also, this method is used to determine the editor as well as the renderer. Finally, the renderer code should NOT be creating a new JLabel every time. So, yes, the solution presented by the poster will work but has several flaws which other attempted to point out. – camickr Aug 13 '11 at 15:10
  • @camickr: I agree. No problem with that. No problem if someone wants to explain the role of getColumnClass and a better way of doing what the OP does. But editing my answer to make it say "The data stored in a JTable can be found in its TableModel, by overriding the getColumnClass(...) method" just makes it incorrect. You don't find what is in a table by overriding getColumnClass. And the vector addition was unnecessary as well, as I explained. I know the edit wasn't malicious, but I found it made my answer less clear, and incorrect. – JB Nizet Aug 13 '11 at 15:22
2

You should already have all the images in your table model. So you just have to get the images from the model, and then save them in your database.

In your cell renderer you have the type Object value, then you use (ImageIcon) value to cast it to an ImageIcon in lbl.setIcon((ImageIcon) value);

You can do the exaclty the same when you get the data from your model:

ImageIcon myIcon = 
         (ImageIcon) base_table.getModel().getValueAt(rowIndex, 3);

where 3 is your columnIndex for the column with images, and rowIndex is the row you want.

Jonas
  • 121,568
  • 97
  • 310
  • 388
  • http://stackoverflow.com/questions/5614875/how-to-set-icon-in-a-column-of-jtable and http://stackoverflow.com/questions/1291948/adding-an-icon-to-jtable-by-overriding-defaulttablecellrenderer and http://stackoverflow.com/questions/3222951/java-put-image-in-jtable-cell +1 – mKorbel Aug 13 '11 at 09:15
0

below is the correct image renderer class.

class SimpleCellRenderer extends DefaultTableCellRenderer{



    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) 

    {
         Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row,
               column);
      ((JLabel)cell).setIcon((Icon)value);
      ((JLabel)cell).setText("");
      ((JLabel)cell).setHorizontalAlignment(JLabel.CENTER);

      if (isSelected) {
         cell.setBackground(Color.white);
      } else {
         cell.setBackground(null);
      }
      //((AbstractTableModel)table.getModel()).fireTableCellUpdated(row,column);

      return cell;
   }


    }

below is the method from where everything gets filled automtically. private void formWindowOpened(java.awt.event.WindowEvent evt)

{                                  
        // TODO add your handling code here:

        fillIcon();  
    } 

   public void fillIcon() {
        int i,j,rowValue,colValue;
         int cols= student.getColumnCount();
         int rows=student.getRowCount();

         for(i =0 ;i<rows ;i++)
         {
             for(j=3; j<cols;j++)
             {
                 rowValue = i;
                 colValue = j;
                 String value = (String)student.getValueAt(rowValue, colValue);

                 if(value.equals("h"))//here h is the value stored in your database which is used to set some icon in place of value h.
{

            ImageIcon icon = new ImageIcon(getClass().getResource("dash.png"));
            student.setValueAt(icon, rowValue, colValue);
            student.getColumnModel().getColumn(colValue).setCellRenderer(new SimpleCellRenderer());
        }