You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
400 lines
13 KiB
400 lines
13 KiB
6 years ago
|
/*
|
||
|
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
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;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* The standard class for rendering (displaying) individual cells
|
||
|
* in a <code>JTable</code>.
|
||
|
* <p>
|
||
|
*
|
||
|
* <strong><a name="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
|
||
|
*/
|
||
|
public class DefaultTableCellRenderer extends JLabel
|
||
|
implements TableCellRenderer, Serializable
|
||
|
{
|
||
|
|
||
|
/**
|
||
|
* 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);
|
||
|
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.
|
||
|
*/
|
||
|
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 <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.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 <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.
|
||
|
* <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 <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 <a href="#override">Implementation Note</a>
|
||
|
* for more information.
|
||
|
*
|
||
|
* @since 1.5
|
||
|
*/
|
||
|
public void invalidate() {}
|
||
|
|
||
|
/**
|
||
|
* 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.
|
||
|
*
|
||
|
* @since 1.5
|
||
|
*/
|
||
|
public void repaint() {
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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"
|
||
|
|| ((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 <a href="#override">Implementation Note</a>
|
||
|
* for more information.
|
||
|
*/
|
||
|
public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { }
|
||
|
|
||
|
|
||
|
/**
|
||
|
* 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 <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}.
|
||
|
*/
|
||
|
public static class UIResource extends DefaultTableCellRenderer
|
||
|
implements javax.swing.plaf.UIResource
|
||
|
{
|
||
|
}
|
||
|
|
||
|
}
|