TITLE:JTableのセルにJCheckBoxを表示して行背景色を変更
#navi(../)
RIGHT:Posted by &author(aterai); at 2008-07-14
*JTableのセルにJCheckBoxを表示して行背景色を変更 [#b7a6c77e]
JTableのセルに表示されているJCheckBoxがチェックされていれば、その行の背景色を変更します。

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

//#screenshot
#ref(http://lh6.ggpht.com/_9Z4BYR88imo/TQTI7wkSMbI/AAAAAAAAATk/uGVLWCqLJUI/s800/CheckedRowColor.png)

**サンプルコード [#h4150100]
#code(link){{
JTable table = new JTable(model) {
  @Override public Component prepareEditor(
        TableCellEditor editor, int row, int column) {
    Component cmp = super.prepareEditor(editor, row, column);
    if(convertColumnIndexToModel(column) == BOOLEAN_COLUMN) {
      JCheckBox c = (JCheckBox)cmp;
      c.setBackground(c.isSelected()? Color.ORANGE:getBackground());
    }
    return cmp;
  }
  @Override public Component prepareRenderer(
        TableCellRenderer renderer, int row, int column) {
    Component c = super.prepareRenderer(renderer, row, column);
    Boolean isChecked = (Boolean) model.getValueAt(
      convertRowIndexToModel(row), BOOLEAN_COLUMN);
    c.setForeground(getForeground());
    c.setBackground(isChecked? Color.ORANGE:getBackground());
    return c;
  }
};
}}

**解説 [#hd518363]
上記のサンプルでは、JTableのprepareEditor、prepareRendererをオーバーライドしてセルエディタや行の背景色を変更しています。

----
TableModelListener でモデルが更新されると、table.repaint()で全体を再描画するのではなく、更新の対象になっている行だけを、以下のように再描画しています。

#code{{
model.addTableModelListener(new TableModelListener() {
  @Override public void tableChanged(TableModelEvent e) {
    if(e.getType()==TableModelEvent.UPDATE) {
      //rowRepaint(table, table.convertRowIndexToView(e.getFirstRow()));
      Rectangle r = table.getCellRect(table.convertRowIndexToView(e.getFirstRow()), 0, true);
      r.width  = table.getWidth();
      table.repaint(r);
      //すこし無駄?: table.repaint();
    }
  }
});
}}


//----
//以下のような、TableCellRendererを利用する方法もあります。
//#code{{
//static class RowColorTableRenderer implements TableCellRenderer {
//  private final Color evenColor = new Color(240, 240, 255);
//  private final TableCellRenderer renderer;
//  public RowColorTableRenderer(TableCellRenderer renderer) {
//    this.renderer = renderer;
//  }
//  @Override public Component getTableCellRendererComponent(
//        JTable table, Object value,
//        boolean isSelected, boolean hasFocus, int row, int column) {
//    Component c = renderer.getTableCellRendererComponent(table, value,
//        isSelected, hasFocus, row, column);
//    TableModel model = table.getModel();
//    Boolean isChecked = (Boolean) model.getValueAt(
//        table.convertRowIndexToModel(row), BOOLEAN_COLUMN);
//    c.setForeground(table.getForeground());
//    c.setBackground(isChecked?Color.ORANGE:table.getBackground());
//    return c;
//  }
//}
//}}

**参考リンク [#z0909a00]
-[http://forums.sun.com/thread.jspa?threadID=5309552 Swing - JTable-Row color issue]

**コメント [#u0d463cd]
- ごちそうさまでした。 -- [[tanuchan]] &new{2009-12-14 (Mon) 04:22:08};
-- まいどありです。 -- [[aterai]] &new{2009-12-16 (水) 21:25:57};
- メモ: [http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6711682 Bug ID: 6711682 JCheckBox in JTable: checkbox doesn't alaways respond to the first mouse click] -- [[aterai]] &new{2010-07-26 (月) 14:18:03};

#comment