15

I want to put individual JComboBoxes into each cells of a JTable. ie. The JComboBox content is not identical for each cell.

I basically would like to be able to just call the following code to add a row of JComboBox into the JTable. Anyone has any idea? Thanks

JComboBox cb1 = new JComboBox(...);
JComboBox cb2 = new JComboBox(...);
model.addRow(new Object[] {"Row name", cb1, cb2} );

JComboBox cb3 = new JComboBox(...);
JComboBox cb4 = new JComboBox(...);
model.addRow(new Object[] {"Row name 2", cb3, cb4} );

The closest example code I can find is as follows. But it is for where JComboBox content is identical for the individual column. Not the solution I need.

TableColumn col = table.getColumnModel().getColumn(vColIndex);
col.setCellEditor(new MyComboBoxEditor(values));

where

public class MyComboBoxEditor extends DefaultCellEditor {
    public MyComboBoxEditor(String[] items) {
        super(new JComboBox(items));
    }
}
Laurel
  • 5,965
  • 14
  • 31
  • 57
Dan
  • 1,711
  • 1
  • 22
  • 36
  • Very easy: table.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(myComboBox)); where you obvioulsy load myComboBox with your values. You do not need any extra class! – Elmue Dec 24 '16 at 04:15

9 Answers9

9

Extend JTable with this code:

@Override
public TableCellEditor getCellEditor(int row, int column) {
   Object value = super.getValueAt(row, column);
   if(value != null) {
      if(value instanceof JComboBox) {
           return new DefaultCellEditor((JComboBox)value);
      }
            return getDefaultEditor(value.getClass());
   }
   return super.getCellEditor(row, column);
}

This will create a unique JComboBox cell editor for each combo box you get the a value for.

user74523
  • 91
  • 1
  • 2
  • 3
    +1 -- one should also should set a custom `TableCellRenderer` on the `TableColumnModel` of the corresponding column in order to ensure that the selected value is drawn instead of a string `javax.swing.JCombobox[...]` while the cell is not being edited. This `TableCellRenderer` should implement `getTableCellRendererComponent(..)` and could return a `JLabel` with the value of `JComboBox.getSelectedItem().toString()` (after checking for null pointers). – Andre Holzner Jun 04 '11 at 09:24
3

I am sure this will solve your problem. Mention in which column you need to set the combo box in .getColumn(int column)

private void addComboToTable(JComboBox combo) {
    TableColumn gradeColumn = YourTable.getColumnModel().getColumn(0);
    JComboBox comboBox = combo;
    comboBox.removeAllItems();
    try {
        comboBox.addItem("Item 1");
        comboBox.addItem("Item 2");
        comboBox.addItem("Item 3");
    } catch (NullPointerException e) {
    } catch (Exception e) {
        e.printStackTrace();
    }
    gradeColumn.setCellEditor(new DefaultCellEditor(comboBox));
}
Mujahid
  • 1,227
  • 5
  • 32
  • 62
2

In addition to cellEditor it is necessary to do the cellRenderer to paint the combobox in the cell, look at this:

 public void example(){  

      TableColumn tmpColum =table.getColumnModel().getColumn(1);
      String[] DATA = { "Data 1", "Data 2", "Data 3", "Data 4" };
      JComboBox comboBox = new JComboBox(DATA);

      DefaultCellEditor defaultCellEditor=new DefaultCellEditor(comboBox);
      tmpColum.setCellEditor(defaultCellEditor);
      tmpColum.setCellRenderer(new CheckBoxCellRenderer(comboBox));
      table.repaint();
   }


/**
   Custom class for adding elements in the JComboBox.
*/
class CheckBoxCellRenderer implements TableCellRenderer {
        JComboBox combo;
        public CheckBoxCellRenderer(JComboBox comboBox) {
            this.combo = new JComboBox();
            for (int i=0; i<comboBox.getItemCount(); i++){
                combo.addItem(comboBox.getItemAt(i));
            }
        }
        public Component getTableCellRendererComponent(JTable jtable, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            combo.setSelectedItem(value);
            return combo;
        }
    }
Adrian
  • 655
  • 6
  • 10
2

You need to override:

Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)

...in TableCellEditor. The value passed in to this method is what you can put in your JComboBox. That means that the 'value' for that particular cell needs to be something that can be translated into a collection. It could potentially just be a List of objects or it could be a POJO with fields that could be made into a JComboBox.

So just edit MyComboBoxEditor to override that method and change your model to allow for an Object that actually represents several other objects.

willcodejavaforfood
  • 43,223
  • 17
  • 81
  • 111
2

The JComboBox content is render identical for each row selection because the JTable does not offer the capability to have more than one editor per column. You have to extend the JTable class to support an additional selection for rows.

This article explains it very well: http://www.javaworld.com/javaworld/javatips/jw-javatip102.html

Ivar
  • 21
  • 1
1
@Override
public TableCellEditor getCellEditor(int row, int column) {
   Object value = super.getValueAt(row, column);
   if(value != null) {
      if(value instanceof JComboBox) {
           return new DefaultCellEditor((JComboBox)value);
      }
            return getDefaultEditor(value.getClass());
   }
   return super.getCellEditor(row, column);
}

And then, override the toString method from JComboBox.

sth
  • 222,467
  • 53
  • 283
  • 367
Rogério
  • 19
  • 1
  • 1
    This actually repeats [another answer](http://stackoverflow.com/a/946949/572834), yet it adds one point: use a customized `JComboBox` so that its `toString()` method returns the selected value. In this case you could use the default `TableCellRenderer` implementation. – Alexey Ivanov Mar 06 '14 at 12:30
0

This page might help you, although it seems you are restricted to having the same combobox in all the cells in a column.

Luke Woodward
  • 63,336
  • 16
  • 89
  • 104
0

You need to create a subclass of JTable to override the method TableCellEditor getCellEditor(int row, int column).

This enables you to set arbitrary cell editors for any row and column combination. The default way is to set the cell editor for an entire column.

(You can also set individual cell renderers by overriding getCellRenderer.)

-8

The easiest way is to implement your own TableModel

public class MyModel extends AbstractTableModel {
    List rows;

    public int getRowCount() {
        return rows.size();
    }

    public int getColumnCount() {
         return 4;
    }

    public Object getValueAt(int row, int column) {
        return rows.get(row).getCol(col);  //assuming your row "Object" has a getCol()
    }

    public Class<?> getColumnClass(int col) {
        return Boolean.class;
    }

    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        rows.get(rowIndex).getCol(columnIndex).setValue(aValue);
    }

}

Load this into you JTable. If you haven't replaced the default cell renderer for Boolean's, all you cells will be rendered as check boxes thanks to you implementation of getColumnClass(). All user input to these check boxes is collected with our setValueAt().

Cogsy
  • 5,584
  • 4
  • 35
  • 47
  • 20
    Err, he asked about a JComboBox, not JCheckBox. How did this answer even get accepted? – Sarel Botha Mar 07 '11 at 17:44
  • @SarelBotha Because OP was last seen at Jan 31 '09 and the correct answer is from Jun 3 '09. Apparently no one thinks this is a problem. See [meta](http://meta.stackexchange.com/questions/161946/rethinking-sort-order-of-answers). – PiTheNumber Feb 04 '13 at 07:06