/* DefaultTableCellRenderer.java --
   Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing.table;

import java.awt.Color;
import java.awt.Component;
import java.awt.Rectangle;
import java.io.Serializable;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;

/**
 * Class to display every cells.
 */
public class DefaultTableCellRenderer extends JLabel
  implements TableCellRenderer, Serializable
{
  static final long serialVersionUID = 7878911414715528324L;

  protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);

  public static class UIResource extends DefaultTableCellRenderer
    implements javax.swing.plaf.UIResource
  {
    public UIResource()
    {
      super();
    }
  }

  /**
   * Stores the color set by setForeground().
   */
  Color foreground;

  /**
   * Stores the color set by setBackground().
   */
  Color background;

  /**
   * Creates a default table cell renderer with an empty border.
   */
  public DefaultTableCellRenderer()
  {
    super();
  }

  /**
   * Assign the unselected-foreground.
   *
   * @param c the color to assign
   */
  public void setForeground(Color c)
  {
    super.setForeground(c);
    foreground = c;
  }

  /**
   * Assign the unselected-background.
   *
   * @param c the color to assign
   */
  public void setBackground(Color c)
  {
    super.setBackground(c);
    background = c;
  }

  /**
   * Look and feel has changed.
   *
   * <p>Replaces the current UI object with the  latest version from
   * the UIManager.</p>
   */
  public void updateUI()
  {
    super.updateUI();
    background = null;
    foreground = null;
  }

  /**
   * Get the string value of the object and pass it to setText().
   *
   * @param table the JTable
   * @param value the value of the object. For the text content,
   *        null is rendered as an empty cell.
   * @param isSelected is the cell selected?
   * @param hasFocus has the cell the focus?
   * @param row the row to render
   * @param column the cell to render
   * 
   * @return this component (the default table cell renderer)
   */
  public Component getTableCellRendererComponent(JTable table, Object value,
                                                 boolean isSelected,
                                                 boolean hasFocus,
                                                 int row, int column)
  {
    setValue(value);
    setOpaque(true);

    if (table == null)
      return this;

    if (isSelected)
      {
        super.setBackground(table.getSelectionBackground());
        super.setForeground(table.getSelectionForeground());
      }
    else
      {
        if (background != null)
          super.setBackground(background);
        else
          super.setBackground(table.getBackground());
        if (foreground != null)
          super.setForeground(foreground);
        else
          super.setForeground(table.getForeground());
      }

    Border b = null;
    if (hasFocus)
      {
        if (isSelected)
          b = UIManager.getBorder("Table.focusSelectedCellHighlightBorder");
        if (b == null)
          b = UIManager.getBorder("Table.focusCellHighlightBorder");
      }
    else
      b = noFocusBorder;
    setBorder(b);

    setFont(table.getFont());

    // If the current background is equal to the table's background, then we
    // can avoid filling the background by setting the renderer opaque.
    Color back = getBackground();
    setOpaque(back != null && back.equals(table.getBackground()));
    
    return this;    
  }

  /**
   * Overriden for performance.
   *
   * <p>This method needs to be overridden in a subclass to actually
   * do something.</p>
   *
   * @return always true
   */
  public boolean isOpaque()
  {
    return true;
  }

  /**
   * Overriden for performance.
   *
   * <p>This method needs to be overridden in a subclass to actually
   * do something.</p>
   */
  public void validate()
  {
    // Does nothing.
  }

  public void revalidate()
  {
    // Does nothing.
  }

  /**
   * Overriden for performance.
   *
   * <p>This method needs to be overridden in a subclass to actually
   * do something.</p>
   */
  public void repaint(long tm, int x, int y, int width, int height)
  {
    // Does nothing.
  }

  /**
   * Overriden for performance.
   *
   * <p>This method needs to be overridden in a subclass to actually
   * do something.</p>
   */
  public void repaint(Rectangle r)
  {
    // Does nothing.
  }

  /**
   * Overriden for performance.
   *
   * <p>This method needs to be overridden in a subclass to actually
   * do something.</p>
   */
  protected void firePropertyChange(String propertyName, Object oldValue,
                                    Object newValue)
  {
    // Does nothing.
  }

  /**
   * Overriden for performance.
   *
   * <p>This method needs to be overridden in a subclass to actually
   * do something.</p>
   */
  public void firePropertyChange(String propertyName, boolean oldValue,
		                 boolean newValue)
  {
    // Does nothing.
  }

  /**
   * Sets the String for this cell.
   * 
   * @param value the string value for this cell; if value is null it
   * sets the text value to an empty string
   */
  protected void setValue(Object value)
  {
    if (value != null)
      setText(value.toString());
    else
      // null is rendered as an empty cell.
      setText("");
  }
}
