• category: swing folder: NoArrowButtonComboCellEditor title: JTableのCellEditorにArrowButtonを非表示にしたJComboBoxを設定 tags: [JTable, CellEditor, JComboBox, ArrowButton, LocalDateTime] author: aterai pubdate: 2015-08-17T01:24:54+09:00 description: JTableのCellEditorとしてArrowButtonを非表示にしたJComboBoxを使用します。 image: https://lh3.googleusercontent.com/-rMRAQF0w4iQ/VdC10-8iyjI/AAAAAAAAN_c/5hX5mZ8KFUg/s800-Ic42/NoArrowButtonComboCellEditor.png

概要

JTableCellEditorとしてArrowButtonを非表示にしたJComboBoxを使用します。

サンプルコード

class LocalDateTimeTableCellEditor extends AbstractCellEditor
                                   implements TableCellEditor {
  private final JComboBox<LocalDateTime> comboBox;
  private LocalDateTime selectedDate;

  public LocalDateTimeTableCellEditor() {
    super();
    UIManager.put("ComboBox.squareButton", Boolean.FALSE);
    comboBox = new JComboBox<LocalDateTime>() {
      @Override public void updateUI() {
        super.updateUI();
        setBorder(BorderFactory.createEmptyBorder());
        setOpaque(true);
        setRenderer(new LocalDateTimeCellRenderer<LocalDateTime>());
        setUI(new BasicComboBoxUI() {
          @Override protected JButton createArrowButton() {
            JButton button = new JButton(); //.createArrowButton();
            button.setBorder(BorderFactory.createEmptyBorder());
            button.setVisible(false);
            return button;
          }
        });
      }
    };
    comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
  }

  @Override public Component getTableCellEditorComponent(
      JTable table, final Object value, boolean isSelected, int row, int column) {
    if (value instanceof LocalDateTime) {
      comboBox.setModel(new DefaultComboBoxModel<LocalDateTime>() {
        @Override public LocalDateTime getElementAt(int index) {
          if (index >= 0 && index < getSize()) {
            return LocalDateTime.now().plusDays(index);
          } else {
            return LocalDateTime.now();
          }
        }

        @Override public int getSize() {
          return 7;
        }

        @Override public Object getSelectedItem() {
          return selectedDate;
        }

        @Override public void setSelectedItem(Object anItem) {
          selectedDate = (LocalDateTime) anItem;
        }
      });
      selectedDate = (LocalDateTime) value;
    }
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        comboBox.setSelectedItem(value);
      }
    });
    return comboBox;
  }

  @Override public Object getCellEditorValue() {
    return comboBox.getSelectedItem();
  }

  @Override public boolean shouldSelectCell(EventObject anEvent) {
    if (anEvent instanceof MouseEvent) {
      MouseEvent e = (MouseEvent) anEvent;
      return e.getID() != MouseEvent.MOUSE_DRAGGED;
    }
    return true;
  }

  @Override public boolean stopCellEditing() {
    if (comboBox.isEditable()) {
      // Commit edited value.
      comboBox.actionPerformed(new ActionEvent(this, 0, ""));
    }
    return super.stopCellEditing();
  }

  @Override public boolean isCellEditable(EventObject e) {
    return true;
  }
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、ArrowButtonを非表示にしたJComboBoxを使用するTableCellEditorを作成しています。

  • このJComboBoxで編集する値はLocalDateTimeなので、DefaultCellEditorは使用しない
    • AbstractCellEditorを継承するTableCellEditorを作成
  • LocalDateTime.now()で取得した日付から7日分をJComboBoxで選択可能になるよう、TableCellEditor#getTableCellEditorComponent(...)内でComboBoxModelを更新

参考リンク

コメント