TITLE:JTableのCellにJCheckBoxを複数配置する

Posted by aterai at 2011-02-28

JTableのCellにJCheckBoxを複数配置する

JTableのセル中にJCheckBoxを複数個配置します。

  • &jnlp;
  • &jar;
  • &zip;
CheckBoxesInTableCell.png

サンプルコード

class CheckBoxEditorRenderer extends AbstractCellEditor
      implements TableCellRenderer, TableCellEditor {
  protected final String[] title = {"r", "w", "x"};
  protected final CheckBoxPanel editor = new CheckBoxPanel(title);
  protected final CheckBoxPanel renderer = new CheckBoxPanel(title);
  protected void updateButtons(CheckBoxPanel p, Object v) {
    Integer i = (Integer)(v==null?0:v);
    p.buttons[0].setSelected((i&(1<<2))!=0);
    p.buttons[1].setSelected((i&(1<<1))!=0);
    p.buttons[2].setSelected((i&(1<<0))!=0);
  }
  @Override public Component getTableCellRendererComponent(JTable table,
      Object value, boolean isSelected, boolean hasFocus, int row, int col) {
    updateButtons(renderer, value);
    return renderer;
  }
  @Override public Component getTableCellEditorComponent(JTable table,
      Object value, boolean isSelected, int row, int column) {
    updateButtons(editor, value);
    return editor;
  }
  @Override public Object getCellEditorValue() {
    int i = 0;
    if(editor.buttons[0].isSelected()) i|=1<<2;
    if(editor.buttons[1].isSelected()) i|=1<<1;
    if(editor.buttons[2].isSelected()) i|=1<<0;
    return i;
  }
}

解説

上記のサンプルでは、JTableのCell内に3つのJCheckBoxを配置したJPanelを作成し、これをCellRendererとCellEditorとして別々に使用しています。JCheckBoxをマウスでクリックすると、そのJCheckBoxの選択状態だけが変化します(注: キーボードからの入力には対応していません)。


ヘッダカラムの移動、リサイズ(JFrameなどのリサイズ)で、チェックした内容が消えてしまわないように、JTable自体に以下の様なMouseListenerを追加してチェックボックスがクリックされるたびにtable.getCellEditor(row, col).stopCellEditing();を呼び出しています。

table.addMouseListener(new MouseAdapter() {
  @Override public void mouseReleased(MouseEvent e) {
    JTable t = (JTable)e.getComponent();
    Point p  = e.getPoint();
    int row  = t.rowAtPoint(p);
    int col  = t.columnAtPoint(p);
    if(t.convertColumnIndexToModel(col)==1) {
      t.getCellEditor(row, col).stopCellEditing();
    }
  }
});

JTableにではなく、CellEditor自体にMouseListenerを追加する方法もあります。

class CheckBoxEditorRenderer2 extends CheckBoxEditorRenderer
                              implements MouseListener {
  private final JTable table;
  public CheckBoxEditorRenderer2(JTable table) {
    super();
    this.table = table;
    editor.addMouseListener(this);
  }
  //Copied form http://tips4java.wordpress.com/2009/07/12/table-button-column/
  private boolean isButtonColumnEditor;
  @Override public void mousePressed(MouseEvent e) {
    if(table.isEditing() &&  table.getCellEditor() == this) {
      isButtonColumnEditor = true;
    }
  }
  @Override public void mouseReleased(MouseEvent e) {
    if(isButtonColumnEditor &&  table.isEditing()) {
      table.getCellEditor().stopCellEditing();
    }
    isButtonColumnEditor = false;
  }
  @Override public void mouseClicked(MouseEvent e) {}
  @Override public void mouseEntered(MouseEvent e) {}
  @Override public void mouseExited(MouseEvent e) {}
}

参考リンク

コメント