TITLE:JTableのセル中にJRadioButtonを配置
#navi(../)
#tags(JTable, JRadioButton, TableCellRenderer, TableCellEditor, JPanel, ActionListener)
RIGHT:Posted by &author(aterai); at 2009-12-21
* JTableのセル中にJRadioButtonを配置 [#xe89889f]
`JTable`のセル中に複数の`JRadioButton`を配置します。[http://www.crionics.com/products/opensource/faq/swing_ex/JTableExamples2.html JTableExamples2]を元に修正を行っています。

#download
#ref(https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTRX5e43uI/AAAAAAAAAhE/QX6qn9jFOB8/s800/RadioButtonsInTableCell.png)

** サンプルコード [#f5687e69]
#code(link){{
class RadioButtonsPanel extends JPanel {
  private static final String OSNAME = System.getProperty("os.name");
  private final String[] answer = { "A", "B", "C" };
  public JRadioButton[] buttons;
  public ButtonGroup bg = new ButtonGroup();
  public RadioButtonsPanel() {
    super();
    setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
    initButtons();
  }
  protected void initButtons() {
    bg = new ButtonGroup();
    buttons = new JRadioButton[answer.length];
    for(int i=0;i<buttons.length;i++) {
      buttons[i] = new JRadioButton(answer[i]);
      buttons[i].setActionCommand(answer[i]);
      buttons[i].setFocusable(false);
      buttons[i].setRolloverEnabled(false);
      add(buttons[i]);
      bg.add(buttons[i]);
    }
  }
  protected void updateSelectedButton(Object v) {
    if("Windows 7".equals(OSNAME)) { //Windows aero?
      removeAll();
      initButtons();
    }
    if("A".equals(v)) {
      buttons[0].setSelected(true);
    }else if("B".equals(v)) {
      buttons[1].setSelected(true);
    }else{
      buttons[2].setSelected(true);
    }
  }
}
}}
#code{{
class RadioButtonsRenderer extends RadioButtonsPanel implements TableCellRenderer {
  public RadioButtonsRenderer() {
    super();
    setName("Table.cellRenderer");
  }
  @Override public Component getTableCellRendererComponent(JTable table,
        Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    updateSelectedButton(value);
    return this;
  }
}
}}
#code{{
class RadioButtonsEditor extends RadioButtonsPanel implements TableCellEditor {
  public RadioButtonsEditor() {
    super();
    ActionListener al = new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        fireEditingStopped();
      }
    };
    for(AbstractButton b: buttons) b.addActionListener(al);
  }
  @Override public Component getTableCellEditorComponent(JTable table,
        Object value, boolean isSelected, int row, int column) {
    updateSelectedButton(value);
    return this;
  }
  @Override public Object getCellEditorValue() {
    return bg.getSelection().getActionCommand();
  }

  //Copid from AbstractCellEditor
  //protected EventListenerList listenerList = new EventListenerList();
  transient protected ChangeEvent changeEvent = null;
//......
}}

** 解説 [#rfb9e48f]
上記のサンプルでは、`JRadioButton`を`3`つ配置した`JPanel`を、`CellRenderer`、`CellEditor`用に`2`つ用意しています。`CellEditor`内の各`JRadioButton`には、クリックされたら編集を終了して更新をコミットするための`ActionListener`を追加しています。

//%%実際にどの`JRadioButton`がクリックされたかなどは、以下のように、`JTable`に追加した`MouseListener`で処理するようになっています。%%
//
//#code{{
//table.addMouseListener(new MouseAdapter() {
//  @Override public void mouseReleased(MouseEvent e) {
//    JTable t = (JTable)e.getComponent();
//    Point pt = e.getPoint();
//    int row  = t.rowAtPoint(pt);
//    int col  = t.columnAtPoint(pt);
//    if(t.convertRowIndexToModel(row)>=0 && t.convertColumnIndexToModel(col)==1) {
//      TableCellEditor ce = t.getCellEditor(row, col);
//      //http://tips4java.wordpress.com/2009/07/12/table-button-column/
//      ce.stopCellEditing();
//      Component c = ce.getTableCellEditorComponent(t, null, true, row, col);
//      Point p = SwingUtilities.convertPoint(t, pt, c);
//      Component b = SwingUtilities.getDeepestComponentAt(c, p.x, p.y);
//      if(b instanceof JRadioButton) ((JRadioButton)b).doClick();
//    }
//  }
//});
//}}

** 参考リンク [#xf10c31e]
- [http://www.crionics.com/products/opensource/faq/swing_ex/JTableExamples2.html JTableExamples2]
- [http://tips4java.wordpress.com/2009/07/12/table-button-column/ Table Button Column ≪ Java Tips Weblog]
- [[JTableのセルに複数のJButtonを配置する>Swing/MultipleButtonsInTableCell]]
- [[JTableのCellにJCheckBoxを複数配置する>Swing/CheckBoxesInTableCell]]
- [[JTableのセルにJRadioButton>Swing/RadioButtonCellEditor]]

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