You can use DefaltTableCellRenderer , which is supported by DefaltTableCellRenderer , which you can then use to set the icon.
A better solution would be to extend DefaltTableCellRenderer and override the getTableCellRendererComponent method and apply the icon needed for the cell in the cell
You can apply renderers either by defining the default renderer for the specified Class type, or directly in the column
See How to Use JTables and Using Custom Renderers in Particular
UPDATED with an example
This is approach A , 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; } } }
Update
Why not use JButton / TableCellEditor ? That's why
source share