TITLE:JTableのセル中にJRadioButtonを配置
Posted by aterai at 2009-12-21

JTableのセル中にJRadioButtonを配置

JTableのセル中に複数のJRadioButtonを配置します。JTableExamples2を元に修正を行っています。
  • category: swing folder: RadioButtonsInTableCell title: JTableのセル中にJRadioButtonを配置 tags: [JTable, JRadioButton, TableCellRenderer, TableCellEditor, JPanel, ActionListener] author: aterai pubdate: 2009-12-21T00:36:55+09:00 description: JTableのセル中に複数のJRadioButtonを配置します。 image: https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTRX5e43uI/AAAAAAAAAhE/QX6qn9jFOB8/s800/RadioButtonsInTableCell.png

概要

JTableのセル中に複数のJRadioButtonを配置します。JTableExamples2を元に修正を行っています。
RadioButtonsInTableCell.png

サンプルコード

#spanend
#spanadd
class RadioButtonsPanel extends JPanel {
#spanend
  private final String[] answer = {
      Answer.A.toString(), Answer.B.toString(), Answer.C.toString()};
  public JRadioButton[] buttons;
  public ButtonGroup bg = new ButtonGroup();

#spandel
**サンプルコード [#f5687e69]
#spanend
#spandel
#code{{
#spanend
#spandel
class RadioButtonPanel extends JPanel {
#spanend
  public final JRadioButton[] buttons;
  public final ButtonGroup bg = new ButtonGroup();
  RadioButtonPanel(String[] answer) {
  public RadioButtonsPanel() {
    super();
    setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
    initButtons();
  }
#spanadd

#spanend
  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].setEnabled(true);
      buttons[i].setFocusable(false);
      buttons[i].setRolloverEnabled(false);
      add(buttons[i]);
      bg.add(buttons[i]);
    }
  }
#spanadd

#spanend
  protected void updateSelectedButton(Object v) {
    if (v instanceof Answer) {
      removeAll();
      initButtons();
      switch ((Answer) v) {
        case A:
          buttons[0].setSelected(true);
          break;
        case B:
          buttons[1].setSelected(true);
          break;
        case C:
          buttons[2].setSelected(true);
          break;
        default:
          break;
      }
    }
  }
}
#spandel
class RadioButtonEditorRenderer extends AbstractCellEditor
#spanend
                implements TableCellRenderer, TableCellEditor{
  private final String[] answer = { "A", "B", "C" };
  private final RadioButtonPanel editor;
  private final RadioButtonPanel renderer;
  public RadioButtonEditorRenderer() {
#spanadd

#spanend
#spanadd
class RadioButtonsRenderer extends RadioButtonsPanel implements TableCellRenderer {
#spanend
  public RadioButtonsRenderer() {
    super();
    this.editor   = new RadioButtonPanel(answer);
    this.renderer = new RadioButtonPanel(answer);
    setName("Table.cellRenderer");
  }
  private void setSelectedButton(RadioButtonPanel p, Object v) {
    if("A".equals(v)) {
      p.buttons[0].setSelected(true);
    }else if("B".equals(v)) {
      p.buttons[1].setSelected(true);
    }else{
      p.buttons[2].setSelected(true);
#spanadd

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

#spanend
#spanadd
class RadioButtonsEditor extends RadioButtonsPanel implements TableCellEditor {
#spanend
  public RadioButtonsEditor() {
    super();
    ActionListener al = new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        fireEditingStopped();
      }
    };
    for (AbstractButton b: buttons) {
      b.addActionListener(al);
    }
  }
  @Override public Component getTableCellRendererComponent(
    JTable table, Object value, boolean isSelected,
    boolean hasFocus, int row, int column) {
    setSelectedButton(renderer, value);
    return renderer;
#spanadd

#spanend
  @Override public Component getTableCellEditorComponent(JTable table,
        Object value, boolean isSelected, int row, int column) {
    updateSelectedButton(value);
    return this;
  }
  @Override public Component getTableCellEditorComponent(
    JTable table, Object value, boolean isSelected, int row, int column) {
    setSelectedButton(editor, value);
    return editor;
  }
#spanadd

#spanend
  @Override public Object getCellEditorValue() {
    return editor.bg.getSelection().getActionCommand();
    // bug: return bg.getSelection().getActionCommand();
    return Answer.valueOf(bg.getSelection().getActionCommand());
  }
#spandel
}
#spanend
#spanadd

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

解説

上記のサンプルでは、JRadioButtonを3つ配置したJPanelを、CellRenderer、CellEditor用に二つ用意しています。実際にどのJRadioButtonがクリックされたかなどは、以下のように、JTableに追加したMouseListenerで処理するようになっています。

解説

上記のサンプルでは、JRadioButton3つ配置したJPanelCellRendererCellEditor用に2つ用意しています。CellEditor内の各JRadioButtonにはクリックされたら編集を終了して更新をTableModelにコミットするためのActionListenerを追加しています。
#spanend
#spandel
table.addMouseListener(new MouseAdapter() {
#spanend
  @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();
    }
  }
#spandel
});
#spanend
#spandel

参考リンク

参考リンク

コメント

コメント