カスタムのセルレンダラーを作りセルの値によって背景色を変更する方法

前の記事「デフォルトセルレンダラーを使って中央揃えにする方法」では、 デフォルトセルレンダラーをいじって、中央揃えで表示する方法を示しました。

その結果が次のような画面でした。

この記事では、カスタムのセルレンダラーを実装して、データの値によって背景色を変更する方法を示します。

次のような画面を作ります。最初のカラムで X が赤、Y が青にしています。

カスタムで作るといっても、ベースはデフォルトセルレンダラーです。 そこから派生して明示的にセルレンダラークラスを作るということです。

JTable は次のように作りました。

package com.keicode.java.testapp;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.TableColumn;

@SuppressWarnings("serial")
public class TableTest15 extends JFrame {
  public TableTest15() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(350, 150);

    JTable table = new JTable();
    MyTableModel2 tableModel = new MyTableModel2();
    table.setModel(tableModel);
    
    MyTableCellRenderer tableCellRenderer = new MyTableCellRenderer();
    TableColumn col = table.getColumnModel().getColumn(0);
    col.setCellRenderer(tableCellRenderer);
    
    JScrollPane scrollPane = new JScrollPane(table);
    add(scrollPane);
  }
  
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        TableTest15 app = new TableTest15();
        app.setVisible(true);
      }
    });
  }
}

ここでテーブルモデルの MyTableModel2 は以前と同様ですが、念のため再度載せて置きます。

package com.keicode.java.testapp;

import javax.swing.table.AbstractTableModel;

@SuppressWarnings("serial")
class MyTableModel2 extends AbstractTableModel {

  Object[][] data = {
      {"X", "100", true},
      {"X", "200", false},
      {"X", "300", false},
      {"Y", "400", false},
      {"Y", "500", false},
      {"Z", "600", false},
      {"Z", "700", false}};
  
  String[] columns = {"Column 0", "Column 1", "Column 2"};
  
  @Override
  public Class<?> getColumnClass(int columnIndex) {
    return data[0][columnIndex].getClass();
  }

  @Override
  public String getColumnName(int column) {
    return columns[column];
  }

  @Override
  public int getRowCount() {
    return data.length;
  }

  @Override
  public int getColumnCount() {
    return columns.length;
  }

  @Override
  public Object getValueAt(int rowIndex, int columnIndex) {
    return data[rowIndex][columnIndex];
  }
    
}

さて、次が本題のテーブルセルレンダラーです。DefaultTableCellRenderer から派生して作成しています。

package com.keicode.java.testapp;

import java.awt.Color;
import java.awt.Component;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

@SuppressWarnings("serial")
public class MyTableCellRenderer extends DefaultTableCellRenderer {
  
  @Override
  public Component getTableCellRendererComponent(
    JTable table, 
    Object value, 
    boolean isSelected, 
    boolean hasFocus,
    int row, 
    int column) {

    Component renderer = super.getTableCellRendererComponent(
        table, 
        value, 
        isSelected, 
        hasFocus, 
        row, 
        column);

    if(value == null) {
      return renderer;
    }
    
    setHorizontalAlignment(JLabel.CENTER);
    
    switch(value.toString().toUpperCase()) {
    case "X": 
      setBackground(Color.RED);
      break;
    case "Y":
      setBackground(Color.BLUE);
      break;
    default:
      setBackground(Color.WHITE);
    }
    
    return renderer;
  }
}

要はデフォルトセルレンダラーをデータの値によっていじっているに過ぎないので、 「デフォルトセルレンダラーを使って中央揃えにする方法」で行ったものと考え方は同じです。

しかし、実装としてはコード量が増えればソースを分ける方がわかりやすいし、間違いも少なく、再利用もしやすいので優れていると言えます。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Java 入門