/*
 * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javax.swing.table;

import javax.swing.*;
import javax.swing.border.*;

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

import java.io.Serializable;
import sun.swing.DefaultLookup;
import sun.swing.SwingUtilities2;

The standard class for rendering (displaying) individual cells in a JTable.

Implementation Note: This class inherits from JLabel, a standard component class. However JTable employs a unique mechanism for rendering its cells and therefore requires some slightly modified behavior from its cell renderer. The table class defines a single cell renderer and uses it as a as a rubber-stamp for rendering all cells in the table; it renders the first cell, changes the contents of that cell renderer, shifts the origin to the new location, re-draws it, and so on. The standard JLabel component was not designed to be used this way and we want to avoid triggering a revalidate each time the cell is drawn. This would greatly decrease performance because the revalidate message would be passed up the hierarchy of the container to determine whether any other components would be affected. As the renderer is only parented for the lifetime of a painting operation we similarly want to avoid the overhead associated with walking the hierarchy for painting operations. So this class overrides the validate, invalidate, revalidate, repaint, and firePropertyChange methods to be no-ops and override the isOpaque method solely to improve performance. If you write your own renderer, please keep this performance consideration in mind.

Warning: 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. As of 1.4, support for long term storage of all JavaBeans has been added to the java.beans package. Please see XMLEncoder.

Author:Philip Milne
See Also:
/** * The standard class for rendering (displaying) individual cells * in a <code>JTable</code>. * <p> * * <strong><a id="override">Implementation Note:</a></strong> * This class inherits from <code>JLabel</code>, a standard component class. * However <code>JTable</code> employs a unique mechanism for rendering * its cells and therefore requires some slightly modified behavior * from its cell renderer. * The table class defines a single cell renderer and uses it as a * as a rubber-stamp for rendering all cells in the table; * it renders the first cell, * changes the contents of that cell renderer, * shifts the origin to the new location, re-draws it, and so on. * The standard <code>JLabel</code> component was not * designed to be used this way and we want to avoid * triggering a <code>revalidate</code> each time the * cell is drawn. This would greatly decrease performance because the * <code>revalidate</code> message would be * passed up the hierarchy of the container to determine whether any other * components would be affected. * As the renderer is only parented for the lifetime of a painting operation * we similarly want to avoid the overhead associated with walking the * hierarchy for painting operations. * So this class * overrides the <code>validate</code>, <code>invalidate</code>, * <code>revalidate</code>, <code>repaint</code>, and * <code>firePropertyChange</code> methods to be * no-ops and override the <code>isOpaque</code> method solely to improve * performance. If you write your own renderer, * please keep this performance consideration in mind. * <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. As of 1.4, support for long term storage * of all JavaBeans * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. * * @author Philip Milne * @see JTable */
@SuppressWarnings("serial") // Same-version serialization only public class DefaultTableCellRenderer extends JLabel implements TableCellRenderer, Serializable {
An empty Border. This field might not be used. To change the Border used by this renderer override the getTableCellRendererComponent method and set the border of the returned component directly.
/** * An empty <code>Border</code>. This field might not be used. To change the * <code>Border</code> used by this renderer override the * <code>getTableCellRendererComponent</code> method and set the border * of the returned component directly. */
private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
A border without focus.
/** * A border without focus. */
protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER; // 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.
/** * Creates a default table cell renderer. */
public DefaultTableCellRenderer() { super(); setOpaque(true); setBorder(getNoFocusBorder()); setName("Table.cellRenderer"); } private Border getNoFocusBorder() { Border border = DefaultLookup.getBorder(this, ui, "Table.cellNoFocusBorder"); if (System.getSecurityManager() != null) { if (border != null) return border; return SAFE_NO_FOCUS_BORDER; } else if (border != null) { if (noFocusBorder == null || noFocusBorder == DEFAULT_NO_FOCUS_BORDER) { return border; } } return noFocusBorder; }
Overrides JComponent.setForeground to assign the unselected-foreground color to the specified color.
Params:
  • c – set the foreground color to this value
/** * 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 JComponent.setBackground to assign the unselected-background color to the specified color.
Params:
  • c – set the background color to this value
/** * Overrides <code>JComponent.setBackground</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; }
Notification from the UIManager that the look and feel [L&F] has changed. Replaces the current UI object with the latest version from the UIManager.
See Also:
  • updateUI.updateUI
/** * Notification from the <code>UIManager</code> that the look and feel * [L&amp;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.

During a printing operation, this method will be called with isSelected and hasFocus values of false to prevent selection and focus from appearing in the printed output. To do other customization based on whether or not the table is being printed, check the return value from JComponent.isPaintingForPrint().

Params:
  • table – the JTable
  • value – the value to assign to the cell at [row, column]
  • isSelected – true if cell is selected
  • hasFocus – true if cell has focus
  • row – the row of the cell to render
  • column – the column of the cell to render
See Also:
Returns:the default table cell renderer
/** * * Returns the default table cell renderer. * <p> * During a printing operation, this method will be called with * <code>isSelected</code> and <code>hasFocus</code> values of * <code>false</code> to prevent selection and focus from appearing * in the printed output. To do other customization based on whether * or not the table is being printed, check the return value from * {@link javax.swing.JComponent#isPaintingForPrint()}. * * @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 hasFocus 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 * @see javax.swing.JComponent#isPaintingForPrint() */
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (table == null) { return this; } Color fg = null; Color bg = null; JTable.DropLocation dropLocation = table.getDropLocation(); if (dropLocation != null && !dropLocation.isInsertRow() && !dropLocation.isInsertColumn() && dropLocation.getRow() == row && dropLocation.getColumn() == column) { fg = DefaultLookup.getColor(this, ui, "Table.dropCellForeground"); bg = DefaultLookup.getColor(this, ui, "Table.dropCellBackground"); isSelected = true; } if (isSelected) { super.setForeground(fg == null ? table.getSelectionForeground() : fg); super.setBackground(bg == null ? table.getSelectionBackground() : bg); } else { Color background = unselectedBackground != null ? unselectedBackground : table.getBackground(); if (background == null || background instanceof javax.swing.plaf.UIResource) { Color alternateColor = DefaultLookup.getColor(this, ui, "Table.alternateRowColor"); if (alternateColor != null && row % 2 != 0) { background = alternateColor; } } super.setForeground(unselectedForeground != null ? unselectedForeground : table.getForeground()); super.setBackground(background); } setFont(table.getFont()); if (hasFocus) { Border border = null; if (isSelected) { border = DefaultLookup.getBorder(this, ui, "Table.focusSelectedCellHighlightBorder"); } if (border == null) { border = DefaultLookup.getBorder(this, ui, "Table.focusCellHighlightBorder"); } setBorder(border); if (!isSelected && table.isCellEditable(row, column)) { Color col; col = DefaultLookup.getColor(this, ui, "Table.focusCellForeground"); if (col != null) { super.setForeground(col); } col = DefaultLookup.getColor(this, ui, "Table.focusCellBackground"); if (col != null) { super.setBackground(col); } } } else { setBorder(getNoFocusBorder()); } setValue(value); 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 Implementation Note for more information.
/** * Overridden for performance reasons. * See the <a href="#override">Implementation Note</a> * for more information. */
public boolean isOpaque() { Color back = getBackground(); Component p = getParent(); if (p != null) { p = p.getParent(); } // p should now be the JTable. boolean colorMatch = (back != null) && (p != null) && back.equals(p.getBackground()) && p.isOpaque(); return !colorMatch && super.isOpaque(); }
Overridden for performance reasons. See the Implementation Note for more information.
Since:1.5
/** * Overridden for performance reasons. * See the <a href="#override">Implementation Note</a> * for more information. * * @since 1.5 */
public void invalidate() {}
Overridden for performance reasons. See the Implementation Note for more information.
/** * Overridden for performance reasons. * See the <a href="#override">Implementation Note</a> * for more information. */
public void validate() {}
Overridden for performance reasons. See the Implementation Note for more information.
/** * Overridden for performance reasons. * See the <a href="#override">Implementation Note</a> * for more information. */
public void revalidate() {}
Overridden for performance reasons. See the Implementation Note for more information.
/** * 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 Implementation Note for more information.
/** * 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 Implementation Note for more information.
Since:1.5
/** * Overridden for performance reasons. * See the <a href="#override">Implementation Note</a> * for more information. * * @since 1.5 */
public void repaint() { }
Overridden for performance reasons. See the Implementation Note for more information.
/** * 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" || propertyName == "labelFor" || propertyName == "displayedMnemonic" || ((SwingUtilities2.isScaleChanged(propertyName, oldValue, newValue) || propertyName == "font" || propertyName == "foreground") && oldValue != newValue && getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey) != null)) { super.firePropertyChange(propertyName, oldValue, newValue); } }
Overridden for performance reasons. See the Implementation Note for more information.
/** * 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 object for the cell being rendered to value.
Params:
  • value – the string value for this cell; if value is null it sets the text value to an empty string
See Also:
/** * Sets the <code>String</code> object 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 DefaultTableCellRenderer that implements UIResource. DefaultTableCellRenderer doesn't implement UIResource directly so that applications can safely override the cellRenderer property with DefaultTableCellRenderer subclasses.

Warning: 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. As of 1.4, support for long term storage of all JavaBeans has been added to the java.beans package. Please see XMLEncoder.

/** * 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. As of 1.4, support for long term storage * of all JavaBeans * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. */
@SuppressWarnings("serial") // Same-version serialization only public static class UIResource extends DefaultTableCellRenderer implements javax.swing.plaf.UIResource {
Constructs a UIResource.
/** * Constructs a {@code UIResource}. */
public UIResource() {} } }