Search code examples
javaswingjtablejcomboboxjcheckbox

Insert a JCheckBox and JComboBox inside a JTable


I'm trying to insert a CheckBox and a ComboBox on the same column, but it's a little bit tricky, I can't seem to find a solution for rendering both at once. Can someone help me with this? I would appreciate the help.

The Jtable I'm trying to achieve is below :

enter image description here


Solution

  • Probably this example will solve your problems

    import java.awt.Component;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.swing.DefaultCellEditor;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.SwingUtilities;
    import javax.swing.WindowConstants;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableCellEditor;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableModel;
    
    /**
     * <code>CellBasedTable</code>.
     */
    public class CellBasedTable extends JTable {
    
        private static class TableCell {
    
            /** Column of the cell. */
            private final int column;
    
            /** Row of the cell. */
            private final int row;
    
            /**
             * Creates cell with the given row and column.
             * 
             * @param aRow row of cell.
             * @param aColumn column of cell.
             */
            public TableCell(int aRow, int aColumn) {
                row = aRow;
                column = aColumn;
            }
    
            @Override
            public boolean equals(Object obj) {
                if (obj instanceof TableCell) {
                    TableCell another = (TableCell) obj;
                    return row == another.row && column == another.column;
                }
                return false;
            }
    
            @Override
            public int hashCode() {
                return Arrays.hashCode(new int[] {row, column});
            }
        }
    
        private final Map<TableCell, TableCellRenderer> rendererMap = new HashMap<>();
    
        private final Map<TableCell, TableCellEditor> editorMap = new HashMap<>();
    
        /**
         * 
         */
        public CellBasedTable() {
        }
    
        /**
         * @param dm
         */
        public CellBasedTable(TableModel dm) {
            super(dm);
        }
    
        public void setCellRenderer(int row, int column, TableCellRenderer r) {
            rendererMap.put(new TableCell(row, column), r);
        }
    
        @Override
        public TableCellRenderer getCellRenderer(int row, int column) {
            return rendererMap.getOrDefault(new TableCell(row, column), super.getCellRenderer(row, column));
        }
    
        public void setCellEditor(int row, int column, TableCellEditor e) {
            editorMap.put(new TableCell(row, column), e);
        }
    
        @Override
        public TableCellEditor getCellEditor(int row, int column) {
            return editorMap.getOrDefault(new TableCell(row, column), super.getCellEditor(row, column));
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(CellBasedTable::startDemo);
        }
    
        private static void startDemo() {
            DefaultTableModel model = new DefaultTableModel(new Object[] {"Subject", "Value"}, 0);
            model.addRow(new Object[] {"name", "Variable"});
            model.addRow(new Object[] {"Stored", Boolean.TRUE});
            model.addRow(new Object[] {"Stroed Arguments", "job"});
            JComboBox<String> combo = new JComboBox<>(new String[] {"task", "job", "rule"});
            CellBasedTable tbl = new CellBasedTable(model);
            tbl.setCellRenderer(1, 1, tbl.getDefaultRenderer(Boolean.class));
            tbl.setCellEditor(1, 1, tbl.getDefaultEditor(Boolean.class));
            tbl.setCellRenderer(2, 1, new ComboRenderer(combo));
            tbl.setCellEditor(2, 1, new DefaultCellEditor(combo));
            tbl.setRowHeight(24);
            JFrame frm = new JFrame("TableTest");
            frm.add(new JScrollPane(tbl));
            frm.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            frm.pack();
            frm.setLocationRelativeTo(null);
            frm.setVisible(true);
        }
    
        private static class ComboRenderer implements TableCellRenderer {
            private final JComboBox<?> combo;
    
            /**
             * 
             */
            public ComboRenderer(JComboBox<?> combo) {
                this.combo = combo;
            }
    
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
                    int column) {
                combo.setSelectedItem(value);
                combo.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
                combo.setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
                return combo;
            }
        }
    }