Thursday, August 24, 2006

Custom Cell Renderers and Custom Cell Editors in Swing - Part I

JTable provides the ability for individual columns to have different renderers and editors. This is very powerful functionality because you can have a Radio Button in one of the columns or a JButton or JComboBox in some columns.


I went ahead a wrote a small JTable Component that displays a Radio Button in one of its columns. I also customized the component to display the radio button only for specific rows in the column and also added functionality to behave as a radio button group!


The JTable that I wrote has the ability for some external controller to specify
which rows of a particular column must render its value as RadioButtons.
I achieved this by writing an interface with a single method which provided
any renderer with the ability to check if the current row, column can be
rendered by itself.


  /**
   * CellRendererValidator - This is an interface 
   * that will be implemented by any class that 
   wishes <br>to specify whether a CellRenderer 
   * is valid for a specific column and row. <br>
   * This is pretty useful when specific rows of a 
   * column will <i>NOT </i> the renderer set for 
   * the entire column
   
   @author rajeshv
   */
  public static interface CellRendererValidator {
    public boolean isValid(JTable table, 
                          int rowIndex,int colIndex);
  }

I also wrote a TableCellRenderer and TableCellEditor for the RadioButton Column. Here the code for Both.


RadioColumnRenderer:



import java.awt.Color;
import java.awt.Component;

import javax.swing.JRadioButton;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.TableCellRenderer;

public class RadioColumnRenderer extends JRadioButton
    implements TableCellRenderer {
  private CustomJTable.CellRendererValidator 
                                    validator = 
null;

  /**
   
   */
  public RadioColumnRenderer(
      CustomJTable.CellRendererValidator validator) {
    this.validator = validator;
  }

  public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    // this is necessary because we may have 
    // values that are not boolean for
    // som of the columns
    this.setSelected(value != null
        && value.getClass().getName().equals(
            Boolean.class.getName())
        && ((Booleanvalue).booleanValue());

    this.setHorizontalAlignment(
                         
SwingConstants.CENTER);
    this.setOpaque(false);
    this.setBackground(Color.WHITE);
    // request the validator to concur that this 
    // column can be rendered as a JRadioButton
    if (validator != null) {
      if (validator.isValid(table, row, column)) {
        return this;
      }
      return null;
    }
    return this;
  }
}

No comments: