--- /dev/null
+package org.simantics.spreadsheet.ui;\r
+\r
+/*\r
+ * %W% %E%\r
+ *\r
+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.\r
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.\r
+ */\r
+\r
+import java.awt.Color;\r
+import java.awt.Component;\r
+import java.awt.Dimension;\r
+import java.awt.Font;\r
+import java.awt.Rectangle;\r
+import java.io.Serializable;\r
+\r
+import javax.swing.JComponent;\r
+import javax.swing.JLabel;\r
+import javax.swing.JTable;\r
+import javax.swing.SwingConstants;\r
+import javax.swing.border.Border;\r
+import javax.swing.border.EmptyBorder;\r
+import javax.swing.table.TableCellRenderer;\r
+\r
+\r
+/**\r
+ * The standard class for rendering (displaying) individual cells\r
+ * in a <code>JTable</code>.\r
+ * <p>\r
+ *\r
+ * <strong><a name="override">Implementation Note:</a></strong>\r
+ * This class inherits from <code>JLabel</code>, a standard component class. \r
+ * However <code>JTable</code> employs a unique mechanism for rendering\r
+ * its cells and therefore requires some slightly modified behavior\r
+ * from its cell renderer. \r
+ * The table class defines a single cell renderer and uses it as a \r
+ * as a rubber-stamp for rendering all cells in the table; \r
+ * it renders the first cell,\r
+ * changes the contents of that cell renderer, \r
+ * shifts the origin to the new location, re-draws it, and so on.\r
+ * The standard <code>JLabel</code> component was not\r
+ * designed to be used this way and we want to avoid \r
+ * triggering a <code>revalidate</code> each time the\r
+ * cell is drawn. This would greatly decrease performance because the\r
+ * <code>revalidate</code> message would be\r
+ * passed up the hierarchy of the container to determine whether any other\r
+ * components would be affected. \r
+ * As the renderer is only parented for the lifetime of a painting operation\r
+ * we similarly want to avoid the overhead associated with walking the\r
+ * hierarchy for painting operations.\r
+ * So this class\r
+ * overrides the <code>validate</code>, <code>invalidate</code>,\r
+ * <code>revalidate</code>, <code>repaint</code>, and\r
+ * <code>firePropertyChange</code> methods to be \r
+ * no-ops and override the <code>isOpaque</code> method solely to improve\r
+ * performance. If you write your own renderer,\r
+ * please keep this performance consideration in mind.\r
+ * <p>\r
+ *\r
+ * <strong>Warning:</strong>\r
+ * Serialized objects of this class will not be compatible with\r
+ * future Swing releases. The current serialization support is\r
+ * appropriate for short term storage or RMI between applications running\r
+ * the same version of Swing. As of 1.4, support for long term storage\r
+ * of all JavaBeans<sup><font size="-2">TM</font></sup>\r
+ * has been added to the <code>java.beans</code> package.\r
+ * Please see {@link java.beans.XMLEncoder}.\r
+ *\r
+ * @version %I% %G%\r
+ * @author Philip Milne \r
+ * @see JTable\r
+ */\r
+public class Renderer extends JLabel\r
+implements TableCellRenderer, Serializable\r
+{\r
+\r
+ private static final long serialVersionUID = 3056811790713043512L;\r
+\r
+ /**\r
+ * An empty <code>Border</code>. This field might not be used. To change the\r
+ * <code>Border</code> used by this renderer override the \r
+ * <code>getTableCellRendererComponent</code> method and set the border\r
+ * of the returned component directly.\r
+ */\r
+ private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(0, 0, 0, 0);\r
+ private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(0, 0, 0, 0);\r
+ protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER;\r
+\r
+ // We need a place to store the color the JLabel should be returned \r
+ // to after its foreground and background colors have been set \r
+ // to the selection background color. \r
+ // These ivars will be made protected when their names are finalized. \r
+ private Color unselectedForeground; \r
+ private Color unselectedBackground = new Color(240, 40, 40); \r
+\r
+ /**\r
+ * Creates a default table cell renderer.\r
+ */\r
+ public Renderer() {\r
+ super();\r
+ setOpaque(true);\r
+ setBorder(getNoFocusBorder());\r
+ setName("Table.cellRenderer");\r
+ }\r
+\r
+ private Border getNoFocusBorder() {\r
+ Border border = DefaultLookup.getBorder(this, ui, "Table.cellNoFocusBorder");\r
+ if (System.getSecurityManager() != null) {\r
+ if (border != null) return border;\r
+ return SAFE_NO_FOCUS_BORDER;\r
+ } else if (border != null) {\r
+ if (noFocusBorder == null || noFocusBorder == DEFAULT_NO_FOCUS_BORDER) {\r
+ return border;\r
+ }\r
+ }\r
+ return noFocusBorder;\r
+ }\r
+\r
+ /**\r
+ * Overrides <code>JComponent.setForeground</code> to assign\r
+ * the unselected-foreground color to the specified color.\r
+ * \r
+ * @param c set the foreground color to this value\r
+ */\r
+ public void setForeground(Color c) {\r
+ super.setForeground(c); \r
+ unselectedForeground = c; \r
+ }\r
+\r
+ /**\r
+ * Overrides <code>JComponent.setBackground</code> to assign\r
+ * the unselected-background color to the specified color.\r
+ *\r
+ * @param c set the background color to this value\r
+ */\r
+ public void setBackground(Color c) {\r
+ super.setBackground(c); \r
+ unselectedBackground = c; \r
+ }\r
+\r
+ /**\r
+ * Notification from the <code>UIManager</code> that the look and feel\r
+ * [L&F] has changed.\r
+ * Replaces the current UI object with the latest version from the \r
+ * <code>UIManager</code>.\r
+ *\r
+ * @see JComponent#updateUI\r
+ */\r
+ public void updateUI() {\r
+ super.updateUI(); \r
+ setForeground(null);\r
+ setBackground(null);\r
+ }\r
+\r
+ // implements javax.swing.table.TableCellRenderer\r
+ /**\r
+ *\r
+ * Returns the default table cell renderer.\r
+ * <p>\r
+ * During a printing operation, this method will be called with\r
+ * <code>isSelected</code> and <code>hasFocus</code> values of\r
+ * <code>false</code> to prevent selection and focus from appearing\r
+ * in the printed output. To do other customization based on whether\r
+ * or not the table is being printed, check the return value from\r
+ * {@link javax.swing.JComponent#isPaintingForPrint()}.\r
+ *\r
+ * @param table the <code>JTable</code>\r
+ * @param value the value to assign to the cell at\r
+ * <code>[row, column]</code>\r
+ * @param isSelected true if cell is selected\r
+ * @param hasFocus true if cell has focus\r
+ * @param row the row of the cell to render\r
+ * @param column the column of the cell to render\r
+ * @return the default table cell renderer\r
+ * @see javax.swing.JComponent#isPaintingForPrint()\r
+ */\r
+ public Component getTableCellRendererComponent(JTable table, Object value_,\r
+ boolean isSelected, boolean hasFocus, int row, int column) {\r
+\r
+ Color fg = null;\r
+ Color bg = null;\r
+\r
+ CellValue value = (CellValue)value_;\r
+ \r
+ JTable.DropLocation dropLocation = table.getDropLocation();\r
+ if (dropLocation != null\r
+ && !dropLocation.isInsertRow()\r
+ && !dropLocation.isInsertColumn()\r
+ && dropLocation.getRow() == row\r
+ && dropLocation.getColumn() == column) {\r
+\r
+ fg = DefaultLookup.getColor(this, ui, "Table.dropCellForeground");\r
+ bg = DefaultLookup.getColor(this, ui, "Table.dropCellBackground");\r
+\r
+ isSelected = true;\r
+ }\r
+\r
+ int hAlign = value.align & 3;\r
+ int vAlign = value.align >> 2;\r
+ \r
+ if(hAlign == 0) setHorizontalAlignment(SwingConstants.LEFT);\r
+ else if(hAlign == 1) setHorizontalAlignment(SwingConstants.CENTER);\r
+ else if(hAlign == 2) setHorizontalAlignment(SwingConstants.RIGHT);\r
+\r
+ if(vAlign == 0) setVerticalAlignment(SwingConstants.TOP);\r
+ else if(vAlign == 1) setVerticalAlignment(SwingConstants.CENTER);\r
+ else if(vAlign == 2) setVerticalAlignment(SwingConstants.BOTTOM);\r
+ \r
+ if (isSelected) {\r
+ super.setForeground(fg == null ? table.getSelectionForeground()\r
+ : fg);\r
+ super.setBackground(bg == null ? table.getSelectionBackground()\r
+ : bg);\r
+ } else {\r
+ Color background = value.background != null\r
+ ? value.background\r
+ : table.getBackground();\r
+ Color foreground = value.foreground != null\r
+ ? value.foreground\r
+ : table.getForeground();\r
+ super.setForeground(foreground);\r
+ super.setBackground(background);\r
+ }\r
+\r
+ Font f = value.font;\r
+ if(f != null)\r
+ setFont(f);\r
+ else\r
+ setFont(table.getFont());\r
+\r
+ if (hasFocus) {\r
+ Border border = null;\r
+ if (isSelected) {\r
+ border = DefaultLookup.getBorder(this, ui, "Table.focusSelectedCellHighlightBorder");\r
+ }\r
+ if (border == null) {\r
+ border = DefaultLookup.getBorder(this, ui, "Table.focusCellHighlightBorder");\r
+ }\r
+ setBorder(border);\r
+\r
+ if (!isSelected && table.isCellEditable(row, column)) {\r
+ Color col;\r
+ col = DefaultLookup.getColor(this, ui, "Table.focusCellForeground");\r
+ if (col != null) {\r
+ super.setForeground(col);\r
+ }\r
+ col = DefaultLookup.getColor(this, ui, "Table.focusCellBackground");\r
+ if (col != null) {\r
+ super.setBackground(col);\r
+ }\r
+ }\r
+ } else {\r
+ setBorder(value.getBorder());\r
+ }\r
+\r
+ setValue(value.label); \r
+\r
+ return this;\r
+ \r
+ }\r
+\r
+ /*\r
+ * The following methods are overridden as a performance measure to \r
+ * to prune code-paths are often called in the case of renders\r
+ * but which we know are unnecessary. Great care should be taken\r
+ * when writing your own renderer to weigh the benefits and \r
+ * drawbacks of overriding methods like these.\r
+ */\r
+\r
+ /**\r
+ * Overridden for performance reasons.\r
+ * See the <a href="#override">Implementation Note</a> \r
+ * for more information.\r
+ */\r
+ public boolean isOpaque() { \r
+ Color back = getBackground();\r
+ Component p = getParent(); \r
+ if (p != null) { \r
+ p = p.getParent(); \r
+ }\r
+\r
+ // p should now be the JTable. \r
+ boolean colorMatch = (back != null) && (p != null) && \r
+ back.equals(p.getBackground()) && \r
+ p.isOpaque();\r
+ return !colorMatch && super.isOpaque(); \r
+ }\r
+\r
+ /**\r
+ * Overridden for performance reasons.\r
+ * See the <a href="#override">Implementation Note</a> \r
+ * for more information.\r
+ *\r
+ * @since 1.5\r
+ */\r
+ public void invalidate() {}\r
+\r
+ /**\r
+ * Overridden for performance reasons.\r
+ * See the <a href="#override">Implementation Note</a> \r
+ * for more information.\r
+ */\r
+ public void validate() {}\r
+\r
+ /**\r
+ * Overridden for performance reasons.\r
+ * See the <a href="#override">Implementation Note</a> \r
+ * for more information.\r
+ */\r
+ public void revalidate() {}\r
+\r
+ /**\r
+ * Overridden for performance reasons.\r
+ * See the <a href="#override">Implementation Note</a> \r
+ * for more information.\r
+ */\r
+ public void repaint(long tm, int x, int y, int width, int height) {}\r
+\r
+ /**\r
+ * Overridden for performance reasons.\r
+ * See the <a href="#override">Implementation Note</a> \r
+ * for more information.\r
+ */\r
+ public void repaint(Rectangle r) { }\r
+\r
+ /**\r
+ * Overridden for performance reasons.\r
+ * See the <a href="#override">Implementation Note</a> \r
+ * for more information.\r
+ *\r
+ * @since 1.5\r
+ */\r
+ public void repaint() {\r
+ }\r
+\r
+ /**\r
+ * Overridden for performance reasons.\r
+ * See the <a href="#override">Implementation Note</a> \r
+ * for more information.\r
+ */\r
+ protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { \r
+ // Strings get interned...\r
+ if (propertyName=="text"\r
+ || propertyName == "labelFor"\r
+ || propertyName == "displayedMnemonic"\r
+ || ((propertyName == "font" || propertyName == "foreground")\r
+ && oldValue != newValue\r
+ && getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey) != null)) {\r
+\r
+ super.firePropertyChange(propertyName, oldValue, newValue);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Overridden for performance reasons.\r
+ * See the <a href="#override">Implementation Note</a> \r
+ * for more information.\r
+ */\r
+ public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { }\r
+\r
+\r
+ /**\r
+ * Sets the <code>String</code> object for the cell being rendered to\r
+ * <code>value</code>.\r
+ * \r
+ * @param value the string value for this cell; if value is\r
+ * <code>null</code> it sets the text value to an empty string\r
+ * @see JLabel#setText\r
+ * \r
+ */\r
+ protected void setValue(Object value) {\r
+ setText((value == null) ? "" : value.toString());\r
+ }\r
+\r
+\r
+ /**\r
+ * A subclass of <code>DefaultTableCellRenderer</code> that\r
+ * implements <code>UIResource</code>.\r
+ * <code>DefaultTableCellRenderer</code> doesn't implement\r
+ * <code>UIResource</code>\r
+ * directly so that applications can safely override the\r
+ * <code>cellRenderer</code> property with\r
+ * <code>DefaultTableCellRenderer</code> subclasses.\r
+ * <p>\r
+ * <strong>Warning:</strong>\r
+ * Serialized objects of this class will not be compatible with\r
+ * future Swing releases. The current serialization support is\r
+ * appropriate for short term storage or RMI between applications running\r
+ * the same version of Swing. As of 1.4, support for long term storage\r
+ * of all JavaBeans<sup><font size="-2">TM</font></sup>\r
+ * has been added to the <code>java.beans</code> package.\r
+ * Please see {@link java.beans.XMLEncoder}.\r
+ */\r
+ public static class UIResource extends Renderer \r
+ implements javax.swing.plaf.UIResource\r
+ {\r
+ }\r
+\r
+}\r
+\r
+\r