---
category: swing
folder: PanelCellEditorRenderer
title: JTableのCellEditorにJPanelを使用して複数コンポーネントを配置
tags: [JTable, TableCellEditor, TableCellRenderer, JPanel, JButton, JSpinner]
author: aterai
pubdate: 2014-11-17T00:00:08+09:00
description: JTableのCellEditor、CellRendererにJPanelを使用することで、内部に複数コンポーネントを配置したり、セル内の余白を追加します。
image: https://lh4.googleusercontent.com/-_MCc8pkoFGY/VGitX9B0RsI/AAAAAAAANpg/zAG38GESdsU/s800/PanelCellEditorRenderer.png
---
* 概要 [#summary]
`JTable`の`CellEditor`、`CellRenderer`に`JPanel`を使用することで、内部に複数コンポーネントを配置したり、セル内の余白を追加します。

#download(https://lh4.googleusercontent.com/-_MCc8pkoFGY/VGitX9B0RsI/AAAAAAAANpg/zAG38GESdsU/s800/PanelCellEditorRenderer.png)

* サンプルコード [#sourcecode]
#code(link){{
class ButtonsPanel extends JPanel {
  public final List<JButton> buttons = Arrays.asList(
      new JButton("+"), new JButton("-"));
  public final JLabel label = new JLabel() {
    @Override public Dimension getPreferredSize() {
      Dimension d = super.getPreferredSize();
      d.width = 50;
      return d;
    }
  };
  public int i = -1;
  public ButtonsPanel() {
    super();
    label.setHorizontalAlignment(SwingConstants.RIGHT);
    setOpaque(true);
    add(label);
    for (JButton b : buttons) {
      b.setFocusable(false);
      b.setRolloverEnabled(false);
      add(b);
    }
  }
}

class ButtonsRenderer extends ButtonsPanel implements TableCellRenderer {
  public ButtonsRenderer() {
    super();
    setName("Table.cellRenderer");
  }
  @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    this.setBackground(isSelected ? table.getSelectionBackground()
                                  : table.getBackground());
    label.setForeground(isSelected ? table.getSelectionForeground()
                                   : table.getForeground());
    label.setText(Objects.toString(value, ""));
    return this;
  }
}

class ButtonsEditor extends ButtonsPanel implements TableCellEditor {
  public ButtonsEditor() {
    super();
    buttons.get(0).addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        i++;
        label.setText("" + i);
        fireEditingStopped();
      }
    });

    buttons.get(1).addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        i--;
        label.setText("" + i);
        fireEditingStopped();
      }
    });

    addMouseListener(new MouseAdapter() {
      @Override public void mousePressed(MouseEvent e) {
        fireEditingStopped();
      }
    });
  }

  @Override public Component getTableCellEditorComponent(
    JTable table, Object value, boolean isSelected, int row, int column) {
    this.setBackground(table.getSelectionBackground());
    label.setForeground(table.getSelectionForeground());
    i = (Integer) value;
    label.setText("" + i);
    return this;
  }

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

  // Copied from AbstractCellEditor
  // ...
}}

* 解説 [#explanation]
- `0`列目: `JPanel` + `JSpinner`
-- `TableCellEditor`、`TableCellRenderer`に`JSpinner`を配置した`JPanel`を使用
-- `JPanel`に`GridBagLayout`を指定し、`insets = new Insets(0, 10, 0, 10)`、`fill = GridBagConstraints.HORIZONTAL`で余白を設定
-- `TableCellEditor`と`TableCellRenderer`に`JSpinner`を配置した`JPanel`を使用
-- `JPanel`に`GridBagLayout`を指定して`insets = new Insets(0, 10, 0, 10)`、`fill = GridBagConstraints.HORIZONTAL`で余白を設定
-- [[JTableのCellEditorに設定したJComboBoxに余白を追加する>Swing/ComboBoxCellEditorInsets]]
- `1`列目: `JPanel` + `JLabel` + `JButton`
-- `TableCellEditor`、`TableCellRenderer`に`JLabel`と`2`つの`JButton`を配置した`JPanel`を使用
-- `TableCellEditor`と`TableCellRenderer`に`JLabel`と`2`つの`JButton`を配置した`JPanel`を使用
-- `JPanel`には`FlowLayout`を指定
--- カラム幅が狭くなって折り返しが発生してもセルの高さは変化しないのでコンポーネントが見切れてしまう
-- [[JTableのセルに複数のJButtonを配置する>Swing/MultipleButtonsInTableCell]]

* 参考リンク [#reference]
- [[TableCellEditorのレイアウトを変更>Swing/CellEditorLayout]]
- [[JTableのCellEditorに設定したJComboBoxに余白を追加する>Swing/ComboBoxCellEditorInsets]]
- [[JTableのセルに複数のJButtonを配置する>Swing/MultipleButtonsInTableCell]]
- [[CellEditorをJSpinnerにして日付を変更>Swing/DateCellEditor]]

* コメント [#comment]
#comment
#comment