概要

JTableのセルエディタとして編集可能なJComboBoxを適用し、セルの値の追加などを行います。

サンプルコード

class ComboCellEditor extends AbstractCellEditor implements TableCellEditor {
  private final JComboBox<String> combo = new JComboBox<>();

  protected ComboCellEditor() {
    super();
    combo.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
    combo.setEditable(true);
    combo.addActionListener(e -> fireEditingStopped());
  }

  @Override public Component getTableCellEditorComponent(
      JTable table, Object value, boolean isSelected, int row, int column) {
    if (value instanceof ComboBoxModel) {
      @SuppressWarnings("unchecked")
      ComboBoxModel<String> m = (ComboBoxModel<String>) value;
      combo.setModel(m);
    }
    return combo;
  }

  @Override public Object getCellEditorValue() {
    DefaultComboBoxModel<String> m = (DefaultComboBoxModel<String>) combo.getModel();
    if (combo.isEditable()) {
      String str = Objects.toString(combo.getEditor().getItem(), "");
      if (!str.isEmpty() && m.getIndexOf(str) < 0) {
        m.insertElementAt(str, 0);
        combo.setSelectedIndex(0);
      }
    }
    return m;
  }
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、JComboBox#setEditable(true)で編集可能にしたJComboBoxJTableのセルエディタに設定し、セルの値の追加・編集を可能にしています。

  • 各行でJComboBoxの所有するアイテムが異なりまたそれらのアイテムの選択位置も保持する必要があるためTableModelにはDefaultComboBoxModelをモデルデータとして保存
  • JComboBoxJTableのセルエディタとして使用する場合、combo.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);を設定する
    • この設定はドロップダウンリストでカーソルキーによる選択変更してもActionEventなどが発生して編集中止にしないために必要

参考リンク

コメント