4

I am trying to add image Icon in Jtable's cell. I have a code as mentioned below. What should I do for that?

package com.orb;
private final LinkedList<Product> list= new LinkedList<Product>();
private final LinkedList<Boolean> checkList = new LinkedList<Boolean>();
public void addItem(Product customer) {
    list.add(customer);
    checkList.add(false);
    checkList.remove(true);
    fireTableDataChanged();
  }

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

@Override
public int getRowCount() {
    return list.size();
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    Object obj = null;

    if(columnIndex==4){
        setTotal(list.get(rowIndex));
    }

    switch (columnIndex){
        case 0: obj= list.get(rowIndex).getCode() ;break;
        case 1: obj=list.get(rowIndex).getDescription(); break;
        case 2: obj=list.get(rowIndex).getQuantity();break;
        case 3: obj=list.get(rowIndex).getPrice();break;            
        case 4: obj=list.get(rowIndex).getTotal();break;
    }
    return obj;
}

@Override
public Class<?> getColumnClass(int arg0) {

    switch(arg0){
    case 0: case 1: return String.class; 
    case 2: return Integer.class; 
    case 3: case 4: return Double.class;

    //case 5: return ImageIcon.class;
    }
    return super.getColumnClass(arg0);
}

@Override
public boolean isCellEditable(int arg0, int arg1) {
    boolean isCellEditable = false;
    switch(arg1){
    case 2: case 3: isCellEditable= true;break;
    default: isCellEditable= false;break;
    }
    return isCellEditable;
    //return super.isCellEditable(arg0, arg1);
}

@Override
public void setValueAt(Object arg0, int arg1, int arg2) {
    System.out.println("Value seted" +arg0 + arg1 + arg2);

    switch(arg2){
    case 0: break;
    case 1: break;
    case 2: list.get(arg1).setQuantity((Integer)arg0); setTotal(list.get(arg1)); break;
    case 3: list.get(arg1).setPrice((Double)arg0); setTotal(list.get(arg1));break;          
    case 4: list.get(arg1).setTotal((Double)arg0);break;

       //case 0: checkList.set(arg1, (Boolean)arg0);break;
       default:break;
    }

    fireTableDataChanged();
}

public LinkedList<Product> getList() {
    LinkedList<Product> temp = new LinkedList<Product>();
    int index=-1;
    for(Boolean isSelected:checkList){
        index++;
        if(isSelected){
            temp.add(list.get(index));
        }
    }
    return temp;
}

public void deleteRow(int rowNubmer)
{
    list.remove(rowNubmer);     
    fireTableDataChanged();
}

public void setTotal(Product product){
    Double total = 0.0d;
    total = product.getQuantity ()* product.getPrice();
    product.setTotal(total);

}
@Override
public void fireTableDataChanged() {
    super.fireTableDataChanged();       

}

I have a table model like above. I want to add image icon in table cell and want to delete cell when that icon is pressed. How can I do with this code? Please give me full description over this.

Audrius Meškauskas
  • 20,936
  • 12
  • 75
  • 93
  • @ Vincenzo Sanchez I have used class for that but it is in another package. – Balkrushn Viroja Oct 21 '12 at 06:08
  • 1
    *"What should I do for that?"* Write Java code. Where are you stuck, specifically? – Andrew Thompson Oct 21 '12 at 06:19
  • `"What should I do for that?"` I think that use proper way, simple to uncomment `//case 5: return ImageIcon.class;`, in most cases there no reason use Renderer, Renderer is required with Object & Icon or Icon & Object in the one Cell – mKorbel Oct 21 '12 at 06:47
  • 1
    hmmmm maybe I'm wrong but I saw this code by `two-three different users` here, there are very important mistakes, starting with `fireTableRowsDeleted(int firstRow, int lastRow)` instead of `fireTableDataChanged();`, maybe there are a few another `A-Bombs` that killing your `Editor` and `Renderer` on first `fireTableDataChanged();` is called, – mKorbel Oct 21 '12 at 06:55
  • 1
    _Please give me full description over this_ please give me full money for doing that ;-) Seriously, that's not how the site is working: typically, it's you who finds/defines/describes the problems _one-by-one_ (best with an SSCCE), then try to understand the answer. Then update the example with the learned item, go on to the next problem/question ... Here you have two distinct requirements: a) show the icon b) delete the row. Both have been answered more than once, do a bit of research, f.i. by evaluating previous QAs referenced in the sidebar ---> – kleopatra Oct 21 '12 at 10:10

2 Answers2

4

You can use a DefaltTableCellRenderer which is backed by a JLabel which you can then use to set the icon.

The best solution would be to extend DefaltTableCellRenderer and override the getTableCellRendererComponent method and apply the icon as is needed on a cell by cell need

You can apply renderers either by defining the default renderer for a given Class type or directly to the column

Check out How to Use JTables and Using Custom Renderers in particular

UPDATED with example

This is A approach, there are many more...

public class TestTable {

    public static void main(String[] args) {
        new TestTable();
    }

    public TestTable() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JTable table = new JTable();
                table.setGridColor(Color.LIGHT_GRAY);
                table.setShowGrid(true);
                table.setShowHorizontalLines(true);
                table.setShowVerticalLines(true);                
                table.setModel(new TestTableModel());
                table.getColumn("X").setCellRenderer(new DeleteCellRenderer());
                table.getColumn("X").setCellEditor(new DeleteCellEditor());

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    protected class TestTableModel extends AbstractTableModel {

        private List<RowData> rowData;

        public TestTableModel() {
            rowData = new ArrayList<RowData>(25);
            for (int index = 0; index < 10; index++) {
                rowData.add(new RowData(index));
            }
        }

        @Override
        public String getColumnName(int column) {
            return column == 0 ? "Text" : "X";
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            RowData rd = rowData.get(rowIndex);
            return rd.isDeletable();
        }

        @Override
        public int getRowCount() {
            return rowData.size();
        }

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

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            RowData rd = rowData.get(rowIndex);
            return columnIndex == 0 ? rd.getText() : rd.isDeletable();
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            RowData rd = rowData.get(rowIndex);
            if (columnIndex == 1) {
                if (aValue instanceof Boolean && (Boolean)aValue) {
                    rowData.remove(rd);
                    fireTableRowsDeleted(rowIndex, rowIndex);
                }
            }
        }

    }

    public class RowData {

        private String text;
        private boolean deletable;

        public RowData(int row) {
            text = "Row " + row;
            deletable = Math.round(Math.random() * 1) == 0;
        }

        public String getText() {
            return text;
        }

        public boolean isDeletable() {
            return deletable;
        }        
    }

    public class DeleteCellRenderer extends DefaultTableCellRenderer {

        public DeleteCellRenderer() {
            try {
                BufferedImage img = ImageIO.read(getClass().getResource("/Delete.png"));
                setIcon(new ImageIcon(img));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            setText(null);
            if (value instanceof Boolean && (Boolean)value) {
                setEnabled(true);
            } else {
                setEnabled(false);
            }
            return this;
        }        
    }

    public class DeleteCellEditor extends AbstractCellEditor implements TableCellEditor {

        private JLabel label;

        public DeleteCellEditor() {
            label = new JLabel("Delete");
        }

        @Override
        public Object getCellEditorValue() {
            return true;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    stopCellEditing();
                }
            });
            return label;
        }

        @Override
        public boolean isCellEditable(EventObject e) {
            return true;
        }        
    }    
}

Updated

Why not use a JButton/TableCellEditor? Here's why

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • He should rather use a JButton renderer _and editor_ if he wants to delete the cell when pressed. – Mordechai Oct 21 '12 at 06:30
  • @MadProgrammer even I upvoted both post, I think that everything there are uselless, TableModel is wrong with suicide notifiers – mKorbel Oct 21 '12 at 06:57
  • I am much more confused for where to put code. I didn't got that. Please give full description about my code. – Balkrushn Viroja Oct 21 '12 at 07:08
  • 2
    Take the time to read through the [Swing Tutorials](http://docs.oracle.com/javase/tutorial/uiswing/index.html), they are among the best starting off point. – MadProgrammer Oct 21 '12 at 08:08
3

This is done through the custom cell renderer that can extend JLabel. You can easily set the icon for JLabel.

Renderer is a component that must draw itself as a table cell after JTable calls getTableCellRendererComponent passing the cells state and content. It is common for a renderer then to set properties on its own and return this. The renderer can also return some other object as long as it extends Component.

Audrius Meškauskas
  • 20,936
  • 12
  • 75
  • 93