/*
* Copyright (C) 2004 The Concord Consortium, Inc.,
* 10 Concord Crossing, Concord, MA 01742
*
* Web Site: http://www.concord.org
* Email: info@concord.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* END LICENSE */
package org.concord.swing;
import java.awt.Color;
import java.awt.Component;
import java.awt.Rectangle;
import java.io.Serializable;
import java.util.Hashtable;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.table.TableCellRenderer;
public class SwingTableCellRenderer extends JLabel
implements TableCellRenderer, Serializable
{
private Hashtable colors;
protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
// We need a place to store the color the JLabel should be returned
// to after its foreground and background colors have been set
// to the selection background color.
// These ivars will be made protected when their names are finalized.
private Color unselectedForeground;
private Color unselectedBackground;
/**
* Creates a default table cell renderer.
*/
public SwingTableCellRenderer() {
super();
setOpaque(true);
setBorder(noFocusBorder);
}
/**
* Overrides <code>JComponent.setForeground</code> to assign
* the unselected-foreground color to the specified color.
*
* @param c set the foreground color to this value
*/
public void setForeground(Color c) {
super.setForeground(c);
unselectedForeground = c;
}
/**
* Overrides <code>JComponent.setForeground</code> to assign
* the unselected-background color to the specified color.
*
* @param c set the background color to this value
*/
public void setBackground(Color c) {
super.setBackground(c);
unselectedBackground = c;
}
public void setBackground(Color color,int row){
if(color == null) return;
if(colors == null) colors = new Hashtable();
colors.put(new Integer(row),color);
}
public void clearBackground(int row){
if(colors == null) return;
Object key = new Integer(row);
if(colors.containsKey(key)){
colors.remove(key);
}
}
/**
* Notification from the <code>UIManager</code> that the look and feel
* [L&F] has changed.
* Replaces the current UI object with the latest version from the
* <code>UIManager</code>.
*
* @see JComponent#updateUI
*/
public void updateUI() {
super.updateUI();
setForeground(null);
setBackground(null);
}
// implements javax.swing.table.TableCellRenderer
/**
*
* Returns the default table cell renderer.
*
* @param table the <code>JTable</code>
* @param value the value to assign to the cell at
* <code>[row, column]</code>
* @param isSelected true if cell is selected
* @param isFocus true if cell has focus
* @param row the row of the cell to render
* @param column the column of the cell to render
* @return the default table cell renderer
*/
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (isSelected) {
super.setForeground(table.getSelectionForeground());
super.setBackground(table.getSelectionBackground());
}
else {
Color rowColor = (colors == null)?null:(Color) colors.get(new Integer(row));
if(rowColor == null){
rowColor = (unselectedBackground != null) ? unselectedBackground : table.getBackground();
}
super.setForeground((unselectedForeground != null) ? unselectedForeground
: table.getForeground());
super.setBackground(rowColor);
}
setFont(table.getFont());
if (hasFocus) {
setBorder( UIManager.getBorder("Table.focusCellHighlightBorder") );
if (table.isCellEditable(row, column)) {
super.setForeground( UIManager.getColor("Table.focusCellForeground") );
super.setBackground( UIManager.getColor("Table.focusCellBackground") );
}
} else {
setBorder(noFocusBorder);
}
setValue(value);
// ---- begin optimization to avoid painting background ----
Color back = getBackground();
boolean colorMatch = (back != null) && ( back.equals(table.getBackground()) ) && table.isOpaque();
setOpaque(!colorMatch);
// ---- end optimization to aviod painting background ----
return this;
}
/*
* The following methods are overridden as a performance measure to
* to prune code-paths are often called in the case of renders
* but which we know are unnecessary. Great care should be taken
* when writing your own renderer to weigh the benefits and
* drawbacks of overriding methods like these.
*/
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*/
public void validate() {}
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*/
public void revalidate() {}
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*/
public void repaint(long tm, int x, int y, int width, int height) {}
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*/
public void repaint(Rectangle r) { }
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*/
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
// Strings get interned...
if (propertyName=="text") {
super.firePropertyChange(propertyName, oldValue, newValue);
}
}
/**
* Overridden for performance reasons.
* See the <a href="#override">Implementation Note</a>
* for more information.
*/
public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { }
/**
* Sets the string for the cell being rendered to <code>value</code>.
*
* @param value the string value for this cell; if value is
* <code>null</code> it sets the text value to an empty string
* @see JLabel#setText
*
*/
protected void setValue(Object value) {
setText((value == null) ? "" : value.toString());
}
/**
* A subclass of <code>DefaultTableCellRenderer</code> that
* implements <code>UIResource</code>.
* <code>DefaultTableCellRenderer</code> doesn't implement
* <code>UIResource</code>
* directly so that applications can safely override the
* <code>cellRenderer</code> property with
* <code>DefaultTableCellRenderer</code> subclasses.
* <p>
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is appropriate
* for short term storage or RMI between applications running the same
* version of Swing. A future release of Swing will provide support for
* long term persistence.
*/
public static class UIResource extends SwingTableCellRenderer
implements javax.swing.plaf.UIResource
{
}
}