Swing/CheckedRowColor のバックアップの現在との差分(No.2)
TITLE:JTableのセルにJCheckBoxを表示して行背景色を変更
Posted by terai at 2008-07-14
JTableのセルにJCheckBoxを表示して行背景色を変更
JTableのセルに表示されているJCheckBoxがチェックされていれば、その行の背景色を変更します。- 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:
概要
JTable
のセルに表示されているJCheckBox
がチェックされていれば、その行の背景色を変更します。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
#screenshot
サンプルコード
#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
JTable table = new JTable(model) {
@Override
public Component prepareEditor(TableCellEditor editor, int row, int column) {
@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());
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) {
#spanadd
#spanend
@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());
c.setBackground(isChecked ? Color.ORANGE : getBackground());
return c;
}
};
解説
上記のサンプルでは、JTableのprepareEditor、prepareRendererをオーバーライドしてセルエディタや行の背景色を変更しています。解説
上記のサンプルでは、JTable
のprepareEditor
、prepareRenderer
をオーバーライドして編集中のセルエディタ(JCheckBox
)や同じ行の背景色を変更しています。
- - 以下のように、TableCellRendererやCellEditorを利用して、JTableをオーバーライドしない方法*1もあります。
- デフォルトのセルレンダラーの場合、例えばチェックボックスがクリックされてモデルが更新されるとその対応するセルのみ再描画さる
- このサンプルでは対象セルだけではなくそのセルが存在する行全体の背景色を変更しているので、
TableModelListener
でモデルの更新を検出し、以下のようにJTable#repaint(...)
メソッドを使って行を再描画#spandel private static JTable makeTable2(final DefaultTableModel model) { #spanend 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)))); } 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()); #spanadd model.addTableModelListener(new TableModelListener() { #spanend @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); // 一行だけリペイント } }); 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; #spandel } #spanend #spandel static class RowColorTableRenderer implements TableCellRenderer { #spanend 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; } #spandel } #spanend #spanadd }); #spanend