• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTableのセルにJCheckBoxを表示して行背景色を変更
#navi(../)
*JTableのセルにJCheckBoxを表示して行背景色を変更 [#m1cec761]
Posted by [[terai]] at 2008-07-14
---
category: swing
folder: CheckedRowColor
title: JTableのセルにJCheckBoxを表示して行背景色を変更
tags: [JTable, JCheckBox, TableModelListener, TableCellRenderer, TableCellEditor]
author: aterai
pubdate: 2008-07-14T14:18:45+09:00
description: JTableのセルに表示されているJCheckBoxがチェックされていれば、その行の背景色を変更します。
image: https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTI7wkSMbI/AAAAAAAAATk/uGVLWCqLJUI/s800/CheckedRowColor.png
---
* 概要 [#summary]
`JTable`のセルに表示されている`JCheckBox`がチェックされていれば、その行の背景色を変更します。

#contents
#download(https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTI7wkSMbI/AAAAAAAAATk/uGVLWCqLJUI/s800/CheckedRowColor.png)

**概要 [#t2ae1ee3]
JTableのセルに表示されているJCheckBoxがチェックされていれば、その行の背景色を変更します。

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

#screenshot

**サンプルコード [#i0e63eb4]
#code{{
* サンプルコード [#sourcecode]
#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) {
            //System.out.println("JTable: prepareEditor");
            JCheckBox c = (JCheckBox)cmp;
            c.setBackground(c.isSelected()? Color.ORANGE:getBackground());
        }
        return cmp;
  @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());
    }
    @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;
    }
    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;
  }
};
}}

**解説 [#h9e64740]
上記のサンプルでは、JTableのprepareEditor、prepareRendererをオーバーライドしてセルエディタや行の背景色を変更しています。
* 解説 [#explanation]
上記のサンプルでは、`JTable`の`prepareEditor`、`prepareRenderer`をオーバーライドして編集中のセルエディタ(`JCheckBox`)や同じ行の背景色を変更しています。

----
以下のように、TableCellRendererやCellEditorを利用して、JTableをオーバーライドしない方法(([[TWiki . Javadesktop . SwingLabsImperialRules>http://wiki.java.net/bin/view/Javadesktop/SwingLabsImperialRules]]))もあります。
- デフォルトのセルレンダラーの場合、例えばチェックボックスがクリックされてモデルが更新されるとその対応するセルのみ再描画さる
- このサンプルでは対象セルだけではなくそのセルが存在する行全体の背景色を変更しているので、`TableModelListener`でモデルの更新を検出し、以下のように`JTable#repaint(...)`メソッドを使って行を再描画
#code{{
private static JTable makeTable2(final DefaultTableModel model) {
    final JTable table = new JTable(model);
    TableColumnModel columns = table.getColumnModel();
    for(int i=0;i<columns.getColumnCount();i++) {
        columns.getColumn(i).setCellRenderer(new RowColorTableRenderer(
            table.getDefaultRenderer(model.getColumnClass(i))));
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(); // table全体をリペイントする必要はないので
      table.repaint(r);   // 一行だけリペイント
    }
    DefaultCellEditor dce = (DefaultCellEditor)table.getDefaultEditor(model.getColumnClass(BOOLEAN_COLUMN));
    final JCheckBox check = (JCheckBox)dce.getComponent();
    check.addFocusListener(new FocusAdapter() {
        @Override
        public void focusGained(FocusEvent e) {
            System.out.println("JCheckBox: focusGained");
            JCheckBox c = (JCheckBox)e.getSource();
            c.setBackground(c.isSelected()?Color.ORANGE:table.getBackground());
        }
    });
    table.addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent e) {
            int col = table.columnAtPoint(e.getPoint());
            if(table.convertColumnIndexToModel(col)==BOOLEAN_COLUMN) {
                System.out.println("JTable: mousePressed");
                int row = table.rowAtPoint(e.getPoint());
                Boolean isChecked = (Boolean) model.getValueAt(table.convertRowIndexToModel(row), BOOLEAN_COLUMN);
                check.setBackground(isChecked?Color.ORANGE:table.getBackground());
            }
        }
    });
    return table;
}
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;
    }
    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;
    }
}
  }
});
}}

**参考リンク [#y4aec741]
-[[Swing - JTable-Row color issue>http://forum.java.sun.com/thread.jspa?threadID=5309552]]
* 参考リンク [#reference]
- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/JTable.html#prepareRenderer-javax.swing.table.TableCellRenderer-int-int- JTable#prepareRenderer(...) (Java Platform SE 8)]
- [https://community.oracle.com/thread/1361072 Swing - JTable-Row color issue]

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

#comment