Search code examples
javaswingjtablejcombobox

How to make single cell from a given column as drop down in JTable


I have a drop down and simple text field in my JTable and based on the specific value selected in the drop down, I want to change the text field to drop down as well.

Below is the code which I am using for the same and I am able to convert the text field to drop down based on the selection but the problem is that it convert all the text fields in the column to drop down. I just want to change the selected row to drop down, rest should remain as text field.

        comboBox2.addItemListener(new ItemListener() {
        public void itemStateChanged(ItemEvent arg0) {

            String properties = (String) comboBox2.getSelectedItem();
            try {

                switch (properties) {
                case "Choose Object":
                    dd_OR = table.getColumnModel().getColumn(3);

                    model1 = new DefaultComboBoxModel<String>();
                    model1.addElement("");
                    model1.addElement("Snowboarding");
                    model1.addElement("Rowing");
                    model1.addElement("Knitting");

                    JComboBox comboBox3 = new JComboBox<String>(model1);
                    AutoCompleteDecorator.decorate(comboBox3);
                    dd_OR.setCellEditor(new DefaultCellEditor(comboBox3));
                    break;

                }

Solution

  • One way is to override the getCellEditor(...) method of the JTable so you can dynamically determine which editor to use.

    Here is a simple example to get your started:

    import java.awt.*;
    import java.util.List;
    import java.util.ArrayList;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.border.*;
    import javax.swing.table.*;
    
    public class TableComboBoxByRow extends JPanel
    {
        List<String[]> editorData = new ArrayList<String[]>(3);
    
        public TableComboBoxByRow()
        {
            setLayout( new BorderLayout() );
    
            // Create the editorData to be used for each row
    
            editorData.add( new String[]{ "Red", "Blue", "Green" } );
            editorData.add( new String[]{ "Circle", "Square", "Triangle" } );
            editorData.add( new String[]{ "Apple", "Orange", "Banana" } );
    
            //  Create the table with default data
    
            Object[][] data =
            {
                {"Color", "Red"},
                {"Shape", "Square"},
                {"Fruit", "Banana"},
                {"Plain", "Text"}
            };
            String[] columnNames = {"Type","Value"};
    
            DefaultTableModel model = new DefaultTableModel(data, columnNames);
            JTable table = new JTable(model)
            {
                //  Determine editor to be used by row
                public TableCellEditor getCellEditor(int row, int column)
                {
                    int modelColumn = convertColumnIndexToModel( column );
    
                    if (modelColumn == 1 && row < 3)
                    {
                        JComboBox<String> comboBox1 = new JComboBox<String>( editorData.get(row));
                        return new DefaultCellEditor( comboBox1 );
                    }
                    else
                        return super.getCellEditor(row, column);
                }
            };
    
            JScrollPane scrollPane = new JScrollPane( table );
            add( scrollPane );
    //      table.getColumnModel().getColumn(1).setCellRenderer(new ComboBoxRenderer2() );
        }
    /*
        class ComboBoxRenderer2 extends DefaultTableCellRenderer
        {
            @Override
            public Component getTableCellRendererComponent(
                JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
            {
                JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                label.setIcon(UIManager.getIcon("Table.descendingSortIcon"));
                return label;
            }
        }
    */
        private static void createAndShowUI()
        {
            JFrame frame = new JFrame("Table Combo Box by Row");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add( new TableComboBoxByRow() );
            frame.setSize(200, 200);
            frame.setLocationByPlatform( true );
            frame.setVisible( true );
        }
    
        public static void main(String[] args)
        {
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    createAndShowUI();
                }
            });
        }
    }