• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JListのセルにJCheckBoxを使用する
#navi(../)
RIGHT:Posted by &author(aterai); at 2011-03-28
*JListのセルにJCheckBoxを使用する [#z6df133e]
JListのセルにJCheckBoxを使用して、チェックボックスの一覧を作成します。

-&jnlp;
-&jar;
-&zip;

//#screenshot
#ref(https://lh6.googleusercontent.com/_9Z4BYR88imo/TZAiQ_MSc_I/AAAAAAAAA4k/FiVk_o38jyY/s800/CheckBoxCellList.png)

**サンプルコード [#hbcc9907]
#code{{
class CheckBoxCellRenderer extends JCheckBox
    implements ListCellRenderer, MouseListener, MouseMotionListener {
  @Override public Component getListCellRendererComponent(
    JList list,
    Object value,
    int index,
    boolean isSelected,
    boolean cellHasFocus) {
    this.setOpaque(true);
    if(isSelected) {
      this.setBackground(list.getSelectionBackground());
      this.setForeground(list.getSelectionForeground());
    }else{
      this.setBackground(list.getBackground());
      this.setForeground(list.getForeground());
    }
    if(value instanceof CheckBoxNode) {
      this.setSelected(((CheckBoxNode)value).selected);
      if(index==pressedRowIndex) {
        this.getModel().setArmed(true);
        this.getModel().setPressed(true);
      }else{
        this.getModel().setRollover(index==rollOverRowIndex);
        this.getModel().setArmed(false);
        this.getModel().setPressed(false);
      }
    }
    this.setText(value.toString());
    return this;
  }
  private int rollOverRowIndex = -1;
  private int pressedRowIndex = -3;
  @Override public void mouseExited(MouseEvent e) {
    rollOverRowIndex = -1;
    JList c = (JList)e.getSource();
    c.repaint();
  }
  @Override public void mouseClicked(MouseEvent e) {
    if(e.getButton()==MouseEvent.BUTTON1) {
      JList t = (JList)e.getComponent();
      DefaultListModel m = (DefaultListModel)t.getModel();
      Point p = e.getPoint();
      int index  = t.locationToIndex(p);
      CheckBoxNode n = (CheckBoxNode)m.get(index);
      Component c = t.getCellRenderer().getListCellRendererComponent(
          t, n, index, false, false);
      Dimension d = c.getPreferredSize();
      if(d.width>=p.x) {
        m.set(index, new CheckBoxNode(n.text, !n.selected));
        t.repaint();
        t.repaint(t.getCellBounds(index, index));
      }
    }
  }
  @Override public void mouseEntered(MouseEvent e) {}
  private int pressStartIndex = -1;
  @Override public void mousePressed(MouseEvent e) {
    if(e.getButton()==MouseEvent.BUTTON1) {
      JList c = (JList)e.getSource();
      int row = c.locationToIndex(e.getPoint());
      pressStartIndex = row;
      if(row != pressedRowIndex) {
        pressedRowIndex = row;
        c.repaint();
      }
    }
  }
  @Override public void mouseReleased(MouseEvent e) {
    pressedRowIndex = -1;
    pressStartIndex = -1;
  }
  @Override public void mouseDragged(MouseEvent e) {
    JList c = (JList)e.getSource();
    int row = c.locationToIndex(e.getPoint());
    if(row != rollOverRowIndex) {
      rollOverRowIndex = -1;
    }
    if(row != pressedRowIndex) {
      pressedRowIndex = -1;
    }
    if(row == pressStartIndex) {
      pressedRowIndex = row;
    }
    c.repaint();
  }
  @Override public void mouseMoved(MouseEvent e) {
    JList c = (JList)e.getSource();
    int row = c.locationToIndex(e.getPoint());
    if(row != rollOverRowIndex) {
      rollOverRowIndex = row;
      c.repaint();
    }
  }
}
}}

**解説 [#u07c22e4]
- 左: "JCheckBox Cell in JList"
-- JCheckBoxを継承するListCellRendererを設定
-- チェックボックスのロールオーバーなどは、JListにマウスリスナーを設定して表示
-- JList#putClientProperty("List.isFileList", Boolean.TRUE);で、クリックが有効になる領域をチェックボックスの幅に制限
- 右: "JCheckBox in Box"
-- Box.createVerticalBox()にJCheckBoxを追加
-- JCheckBox#setAlignmentX(Component.LEFT_ALIGNMENT);で左揃えに設定

----
[[JTreeの葉ノードをJCheckBoxにする>Swing/CheckBoxNodeTree]]のセルレンダラーを使ったJTreeに、JTree#setRootVisible(false)を設定しても、ほぼ同様のチェックボックスの一覧を作成することができます。

//**参考リンク
**コメント [#d0ea5ae4]
#comment