Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render a checkbox in a JTable?

This is my code to render a JTable and change the color of rows, but it doesn't show a checkbox in column 6, only string (true,false).

Can you provide a solution to fix this?

Thanks in advance.

    public class JLabelRenderer extends JLabel implements TableCellRenderer
{
  private MyJTable myTable;
  /**
   * Creates a Custom JLabel Cell Renderer
   * @param t your JTable implmentation that holds the Hashtable to inquire for
   * rows and colors to paint.
   */
  public JLabelRenderer(MyJTable t)
  {
    this.myTable = t;
  }

  /**
   * Returns the component used for drawing the cell.  This method is
   * used to configure the renderer appropriately before drawing.
   * see TableCellRenderer.getTableCellRendererComponent(...); for more comments on the method
   */
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
  {
    setOpaque(true); //JLabel isn't opaque by default

    setText(value.toString());
    setFont(myTable.getFont());

    if(!isSelected)//if the row is not selected then use the custom color
    setBackground(myTable.getRowToPaint(row));
    else //if the row is selected use the default selection color
    setBackground(myTable.getSelectionBackground());

    //Foreground could be changed using another Hashtable...
    setForeground(myTable.getForeground());

    // Since the renderer is a component, return itself
    return this;
  }

  // The following methods override the defaults for performance reasons
  public void validate() {}
  public void revalidate() {}
  protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}
  public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
}

This is the table:

import javax.swing.JTable;    
import javax.swing.table.*;
import java.util.Hashtable;
import java.awt.Color;

public class MyJTable extends JTable
{
  Hashtable rowsToPaint = new Hashtable(1);

  /**
   * Default Constructor
   */
  public MyJTable()
  {
    super();
  }

  /**
   * Set the TableModel and then render each column with a custom cell renderer
   * @param tm TableModel
   */
  public void setModel(TableModel tm)
  {
    super.setModel(tm);
    renderColumns(new JLabelRenderer(this));
  }

  /**
   * Add a new entry indicating:
   * @param row the row to paint - the first row = 0;
   * @param bgColor background color
   */
  public void addRowToPaint(int row, Color bgColor)
  {
    rowsToPaint.put(new Integer(row), bgColor);
    this.repaint();// you need to repaint the table for each you put in the hashtable.
  }

  /**
   * Returns the user selected BG Color or default BG Color.
   * @param row the row to paint
   * @return Color BG Color selected by the user for the row
   */
  public Color getRowToPaint(int row)
  {
    Color bgColor = (Color)rowsToPaint.get(new Integer(row));
    return (bgColor != null)?bgColor:getBackground();
  }

  /**
   * Render all columns with the specified cell renderer
   * @param cellRender TableCellRenderer
   */
  public  void renderColumns(TableCellRenderer cellRender)
  {
    for(int i=0; i<this.getModel().getColumnCount(); i++)
    {
      renderColumn(this.getColumnModel().getColumn(i), cellRender);
    }
  }

  /**
   * Render a TableColumn with the sepecified Cell Renderer
   * @param col TableColumn
   * @param cellRender TableCellRenderer
   */
  public void renderColumn(TableColumn col, TableCellRenderer cellRender)
  {
    try{
          col.setCellRenderer(cellRender);
        }catch(Exception e){System.err.println("Error rendering column: [HeaderValue]: "+col.getHeaderValue().toString()+" [Identifier]: "+col.getIdentifier().toString());}
  }
}

here is my screen alt text

like image 658
tiendv Avatar asked Nov 11 '10 13:11

tiendv


2 Answers

The best solution to this problem is to implement your own TableModel (typically by sub-classing AbstractTableModel) and implement the getColumnClass(int) method to return Boolean.class for the column you wish to render as a JCheckBox.

There is no need to implement your own TableCellRenderer as the DefaultTableCellRenderer used by JTable by default will automatically render Boolean columns as JCheckboxes.

like image 61
Adamski Avatar answered Sep 21 '22 08:09

Adamski


As you probably know, JTable will render boolean values as checkboxes for you. I suppose that your problem is that, out of the box, you cannot set custom background color per row based on specific criteria in your data. You can create a new TableCellRenderer for your boolean column.

You have a couple options:

  1. you can put a test in your current renderer to determine whether the value passed in is boolean or not, and if so, configure a JCheckbox instance to be returned. This could effect what you want, but you would need to be careful, as your renderer is called often and if you create one-off JCheckboxes, it could cause a lot of churn.

  2. alternatively, you could create a new TableCellRenderer that extends JCheckbox (just as your current one extends JLabel. You would want to refactor your current coloring logic such that it could be shared between the two renderers. Finally, you would want to associate this renderer with your column. You can either do this by setting it as the default renderer on the table for a certain Class (myTable.setDefaultRenderer(Class, TableCellRenderer)), or setting it as the renderer for a specific column (myTable.getColumnModel().getColumn(int).setCellRenderer(TableCellRenderer))

like image 21
akf Avatar answered Sep 22 '22 08:09

akf