概要

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

サンプルコード

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;
  }
};
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、JTableprepareEditorprepareRendererをオーバーライドして編集中のセルエディタ(JCheckBox)や同じ行の背景色を変更しています。

  • デフォルトのセルレンダラーの場合、例えばチェックボックスがクリックされてモデルが更新されるとその対応するセルのみ再描画さる
  • このサンプルでは対象セルだけではなくそのセルが存在する行全体の背景色を変更しているので、TableModelListenerでモデルの更新を検出し、以下のようにJTable#repaint(...)メソッドを使って行を再描画
    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);   // 一行だけリペイント
        }
      }
    });
    

参考リンク

コメント