package org.simantics.spreadsheet.ui; /* * %W% %E% * * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.Rectangle; import java.io.Serializable; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.table.TableCellRenderer; /** * 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 JavaBeansTM * has been added to the java.beans package. * Please see {@link java.beans.XMLEncoder}. * * @version %I% %G% * @author Philip Milne * @see JTable */ public class Renderer extends JLabel implements TableCellRenderer, Serializable { private static final long serialVersionUID = 3056811790713043512L; /** * 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. */ private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(0, 0, 0, 0); private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(0, 0, 0, 0); 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 = new Color(240, 40, 40); /** * Creates a default table cell renderer. */ public Renderer() { 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. * * @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. * * @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 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 * {@link javax.swing.JComponent#isPaintingForPrint()}. * * @param table the JTable * @param value the value to assign to the cell at * [row, column] * @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) { Color fg = null; Color bg = null; CellValue value = (CellValue)value_; 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; } int hAlign = value.align & 3; int vAlign = value.align >> 2; if(hAlign == 0) setHorizontalAlignment(SwingConstants.LEFT); else if(hAlign == 1) setHorizontalAlignment(SwingConstants.CENTER); else if(hAlign == 2) setHorizontalAlignment(SwingConstants.RIGHT); if(vAlign == 0) setVerticalAlignment(SwingConstants.TOP); else if(vAlign == 1) setVerticalAlignment(SwingConstants.CENTER); else if(vAlign == 2) setVerticalAlignment(SwingConstants.BOTTOM); if (isSelected) { super.setForeground(fg == null ? table.getSelectionForeground() : fg); super.setBackground(bg == null ? table.getSelectionBackground() : bg); } else { Color background = value.background != null ? value.background : table.getBackground(); Color foreground = value.foreground != null ? value.foreground : table.getForeground(); super.setForeground(foreground); super.setBackground(background); } Font f = value.font; if(f != null) setFont(f); else 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(value.getBorder()); } setValue(value.label); 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. */ 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 */ public void invalidate() {} /** * Overridden for performance reasons. * See the Implementation Note * for more information. */ public void validate() {} /** * Overridden for performance reasons. * See the Implementation Note * for more information. */ public void revalidate() {} /** * Overridden for performance reasons. * See the Implementation Note * 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. */ public void repaint(Rectangle r) { } /** * Overridden for performance reasons. * See the Implementation Note * for more information. * * @since 1.5 */ public void repaint() { } /** * Overridden for performance reasons. * See the Implementation Note * 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 Implementation Note * for more information. */ public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { } /** * Sets the String object for the cell being rendered to * value. * * @param value the string value for this cell; if value is * null 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 JavaBeansTM * has been added to the java.beans package. * Please see {@link java.beans.XMLEncoder}. */ public static class UIResource extends Renderer implements javax.swing.plaf.UIResource { } }