Помещение JComboBox в JTable

Я хочу поместить отдельные JComboBoxes в каждую ячейку JTable. то есть. Содержимое JComboBox не идентично для каждой ячейки.

В основном я хотел бы просто вызвать следующий код, чтобы добавить строку JComboBox в JTable. У кого-нибудь есть идея? Благодаря

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} );

Самый близкий примерный код, который я могу найти, выглядит следующим образом. Но это касается того, где содержимое JComboBox идентично для отдельного столбца. Не решение, в котором я нуждаюсь.

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

где

public class MyComboBoxEditor extends DefaultCellEditor {
    public MyComboBoxEditor(String[] items) {
        super(new JComboBox(items));
    }
}

Ответы

Ответ 1

Самый простой способ - реализовать собственный 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);
    }

}

Загрузите это в JTable. Если вы не заменили обработчик ячеек по умолчанию для Boolean, все ваши ячейки будут отображаться как флажки благодаря реализации getColumnClass(). Все введенные пользователем эти флажки собираются с помощью нашего setValueAt().

Ответ 2

Расширьте JTable с помощью этого кода:

@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);
}

Это создаст уникальный редактор ячеек JComboBox для каждого поля со списком, для которого вы получите значение.

Ответ 3

Вам нужно переопределить:

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

... в TableCellEditor. Значение, переданное этому методу, - это то, что вы можете добавить в свой JComboBox. Это означает, что "ценность" для этой конкретной ячейки должна быть чем-то, что можно перевести в коллекцию. Это может быть просто список объектов или это может быть POJO с полями, которые можно было бы сделать в JComboBox.

Итак, просто измените MyComboBoxEditor, чтобы переопределить этот метод и изменить вашу модель, чтобы позволить Object, который фактически представляет несколько других объектов.

Ответ 4

Я уверен, что это решит вашу проблему. Упоминайте, в каком столбце вам нужно установить поле со списком в .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));
}

Ответ 5

Содержимое JComboBox отображается одинаково для каждого выбора строки, потому что JTable не предлагает возможности иметь более одного редактора для каждого столбца. Вы должны расширить класс JTable, чтобы поддерживать дополнительный выбор для строк.

В этой статье это очень хорошо объясняется: http://www.javaworld.com/javaworld/javatips/jw-javatip102.html

Ответ 6

В дополнение к cellEditor необходимо, чтобы cellRenderer рисовал combobox в ячейке, посмотрите на это:

 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;
        }
    }

Ответ 7

@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);
}

И затем переопределите метод toString из JComboBox.

Ответ 8

Эта страница может вам помочь, хотя кажется, что вам запрещено иметь одно и то же поле со списком во всех ячейках в столбце.

Ответ 9

Вам нужно создать подкласс JTable, чтобы переопределить метод TableCellEditor getCellEditor (int row, int column).

Это позволяет вам устанавливать произвольные редакторы ячеек для любой комбинации строк и столбцов. По умолчанию используется настройка редактора ячейки для всего столбца.

(Вы также можете настроить отдельные рендереры ячеек, переопределяя getCellRenderer.)