概要

JTableのセルにJButtonを追加し、クリックされたらその行を削除します。

サンプルコード

class DeleteButton extends JButton {
  @Override public void updateUI() {
    super.updateUI();
    setBorder(BorderFactory.createEmptyBorder());
    setFocusable(false);
    setRolloverEnabled(false);
    setText("X");
  }
}

class DeleteButtonRenderer extends DeleteButton implements TableCellRenderer {
  public DeleteButtonRenderer() {
    super();
    setName("Table.cellRenderer");
  }

  @Override public Component getTableCellRendererComponent(JTable table,
      Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    return this;
  }
}

class DeleteButtonEditor extends DeleteButton implements TableCellEditor {
  public DeleteButtonEditor(final JTable table) {
    super();
    addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        int row = table.convertRowIndexToModel(table.getEditingRow());
        fireEditingStopped();
        ((DefaultTableModel) table.getModel()).removeRow(row);
      }
    });
  }

  @Override public Component getTableCellEditorComponent(JTable table,
      Object value, boolean isSelected, int row, int column) {
    return this;
  }

  @Override public Object getCellEditorValue() {
    return "";
  }

  // Copied from AbstractCellEditor
  // protected EventListenerList listenerList = new EventListenerList();
  // transient protected ChangeEvent changeEvent = null;
  // ...
}
View in GitHub: Java, Kotlin

解説

  • セルレンダラーに使用するJButtonは表示専用でクリックイベントなどは無視される
  • セルエディタとして使用するJButtonActionListenerを追加し、このJButtonがクリックされたらAbstractCellEditorからコピーしたfireEditingStopped()メソッドでセルの編集を終了し、TableModelから対象行を削除
    • セルレンダラー、セルエディタがコンポーネント(もしくはDefaultCellEditor)を継承していないとJTableLookAndFeelを変更てもセルレンダラー、セルエディタのupdateUI()が呼ばれない
      • JTable#updateUI()Java 1.6.0JTable#updateSubComponentUI(...)Java 1.7.0SwingUtilities#updateRendererOrEditorUI(Object)を参照
    • AbstractCellEditorを継承していてもupdateUI()は呼ばれない、DefaultCellEditorは継承しづらい…

参考リンク

コメント