/*
* 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&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
{
}
}