Search code examples
javaswingjtablejcomboboxtablecelleditor

Java JTable with JComboBox


I'm trying to place a JComboBox inside a certain column of a JTable. I have this code, and it is working:

    model = new DefaultTableModel();
    JComboBox<String> optionComboCell = new JComboBox<String>();
    optionComboCell.addItem("Option 1");
    optionComboCell.addItem("Option 2");
    optionComboCell.setSelectedIndex(1);


    table = new JTable(model);
    // Adding here all the columns, removed for clarity
    model.addColumn("Options");
    TableColumn optionsColumn = table.getColumn("Options");
    optionsColumn.setCellEditor(new DefaultCellEditor(optionComboCell));

My problem with this, is that it doesn't show as JComboBox until a cell in that column is selected. When the JFrame is loaded, the whole table looks the same, as if all the cells where only text. When clicked, it shows the combo box's arrow and options, but again when deselected, it looks like a regular cell.

Any way to get around that?


Solution

  • Yes, use a JComboBox to render your cells:

    import java.awt.Component;
    import java.util.Enumeration;
    import java.util.Vector;
    
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.SwingUtilities;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableColumn;
    
    public class Test4 {
    
        private static class ComboBoxCellRenderer extends JComboBox implements TableCellRenderer {
    
            public ComboBoxCellRenderer(int column) {
                for (int i = 0; i < 10; i++) {
                    addItem("Cell (" + i + "," + column + ")");
                }
            }
    
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                setSelectedItem(value);
                return this;
            }
        }
    
        protected void initUI() {
            JFrame frame = new JFrame("test");
            frame.add(getTable());
            frame.pack();
            frame.setVisible(true);
        }
    
        private Component getTable() {
            Vector<Vector<String>> data = new Vector<Vector<String>>();
            for (int i = 0; i < 10; i++) {
                Vector<String> row = new Vector<String>();
                for (int j = 0; j < 3; j++) {
                    row.add("Cell (" + i + "," + j + ")");
                }
                data.add(row);
            }
            Vector<String> columns = new Vector<String>();
            columns.add("Column 1");
            columns.add("Column 2");
            columns.add("Column 3");
            DefaultTableModel model = new DefaultTableModel(data, columns);
            JTable table = new JTable(model);
            table.setRowHeight(20);
            int i = 0;
            Enumeration<TableColumn> c = table.getColumnModel().getColumns();
            while (c.hasMoreElements()) {
                TableColumn column = c.nextElement();
                column.setCellRenderer(new ComboBoxCellRenderer(i));
                i++;
            }
            JScrollPane scroll = new JScrollPane(table);
            scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
            return scroll;
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new Test4().initUI();
                }
            });
        }
    }